From a808afdefbd853c6dcea0b9b600f71e5226d860f Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Tue, 26 Jan 2016 17:01:45 -0800 Subject: [PATCH 1/8] metrics sdk changes --- CodePush.js | 10 +- CodePush.m | 92 +++++++++++--- .../microsoft/codepush/react/CodePush.java | 115 +++++++++++++----- package.json | 2 +- request-fetch-adapter.js | 11 +- 5 files changed, 180 insertions(+), 50 deletions(-) diff --git a/CodePush.js b/CodePush.js index 993a412..cfe8f3d 100644 --- a/CodePush.js +++ b/CodePush.js @@ -103,9 +103,9 @@ function getPromisifiedSdk(requestFetchAdapter, config) { }); }; - sdk.reportStatusDeploy = (deployedPackage, status) => { + sdk.reportStatusDeploy = (deployedPackage, status, fromLabelOrAppVersion, fromDeploymentKey) => { return new Promise((resolve, reject) => { - module.exports.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, (err) => { + module.exports.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, fromLabelOrAppVersion, fromDeploymentKey, (err) => { if (err) { reject(err); } else { @@ -140,13 +140,15 @@ async function notifyApplicationReady() { const statusReport = await NativeCodePush.getNewStatusReport(); if (statusReport) { const config = await getConfiguration(); + const fromLabelOrAppVersion = statusReport.fromLabelOrAppVersion; + const fromDeploymentKey = statusReport.fromDeploymentKey || config.deploymentKey; if (statusReport.appVersion) { const sdk = getPromisifiedSdk(requestFetchAdapter, config); - sdk.reportStatusDeploy(); + sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, fromLabelOrAppVersion, fromDeploymentKey); } else { config.deploymentKey = statusReport.package.deploymentKey; const sdk = getPromisifiedSdk(requestFetchAdapter, config); - sdk.reportStatusDeploy(statusReport.package, statusReport.status); + sdk.reportStatusDeploy(statusReport.package, statusReport.status, fromLabelOrAppVersion, fromDeploymentKey); } } } diff --git a/CodePush.m b/CodePush.m index 3b69041..1dd6d5f 100644 --- a/CodePush.m +++ b/CodePush.m @@ -161,6 +161,11 @@ static NSString *const PackageIsPendingKey = @"isPending"; [[NSNotificationCenter defaultCenter] removeObserver:self]; } +- (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier +{ + return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; +} + - (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package { // Because deploymentKeys can be dynamically switched, we use a @@ -174,6 +179,18 @@ static NSString *const PackageIsPendingKey = @"isPending"; } } +- (NSString *)getPreviousStatusReportIdentifier +{ + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + NSString *sentStatusReportIdentifier = [preferences objectForKey:LastDeploymentReportKey]; + return sentStatusReportIdentifier; +} + +- (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier +{ + return [[statusReportIdentifier componentsSeparatedByString:@":"] lastObject]; +} + - (instancetype)init { self = [super init]; @@ -212,13 +229,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; } } -- (BOOL)isDeploymentStatusNotYetReported:(NSString *)appVersionOrPackageIdentifier -{ - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - NSString *sentStatusReportIdentifier = [preferences objectForKey:LastDeploymentReportKey]; - return sentStatusReportIdentifier == nil || ![sentStatusReportIdentifier isEqualToString:appVersionOrPackageIdentifier]; -} - /* * This method checks to see whether a specific package hash * has previously failed installation. @@ -267,6 +277,11 @@ static NSString *const PackageIsPendingKey = @"isPending"; return updateIsPending; } +- (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier +{ + return statusReportIdentifier != nil && [statusReportIdentifier containsString:@":"]; +} + /* * This method updates the React Native bridge's bundle URL * to point at the latest CodePush update, and then restarts @@ -542,9 +557,13 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve NSDictionary *lastFailedPackage = [failedUpdates lastObject]; if (lastFailedPackage) { NSString *lastFailedPackageIdentifier = [self getPackageStatusReportIdentifier:lastFailedPackage]; - if (lastFailedPackageIdentifier && [self isDeploymentStatusNotYetReported:lastFailedPackageIdentifier]) { + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (lastFailedPackageIdentifier && (previousStatusReportIdentifier == nil || ![previousStatusReportIdentifier isEqualToString:lastFailedPackageIdentifier])) { [self recordDeploymentStatusReported:lastFailedPackageIdentifier]; - resolve(@{ @"package": lastFailedPackage, @"status": DeploymentFailed }); + resolve(@{ + @"package": lastFailedPackage, + @"status": DeploymentFailed + }); return; } } @@ -555,19 +574,64 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; if (!error && currentPackage) { NSString *currentPackageIdentifier = [self getPackageStatusReportIdentifier:currentPackage]; - if (currentPackageIdentifier && [self isDeploymentStatusNotYetReported:currentPackageIdentifier]) { - [self recordDeploymentStatusReported:currentPackageIdentifier]; - resolve(@{ @"package": currentPackage, @"status": DeploymentSucceeded }); - return; + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (currentPackageIdentifier) { + if (previousStatusReportIdentifier == nil) { + [self recordDeploymentStatusReported:currentPackageIdentifier]; + resolve(@{ + @"package": currentPackage, + @"status": DeploymentSucceeded + }); + return; + } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { + [self recordDeploymentStatusReported:currentPackageIdentifier]; + if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *fromDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *fromLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + resolve(@{ + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"fromDeploymentKey": fromDeploymentKey, + @"fromLabelOrAppVersion": fromLabel + }); + } else { + // Previous status report was with a binary app version. + resolve(@{ + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"fromLabelOrAppVersion": previousStatusReportIdentifier + }); + } + return; + } } } } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { // Check if the current appVersion has been reported. NSString *appVersion = [[CodePushConfig current] appVersion]; - if ([self isDeploymentStatusNotYetReported:appVersion]) { + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (previousStatusReportIdentifier == nil) { [self recordDeploymentStatusReported:appVersion]; resolve(@{ @"appVersion": appVersion }); return; + } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { + [self recordDeploymentStatusReported:appVersion]; + if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *fromDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *fromLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + resolve(@{ + @"appVersion": appVersion, + @"fromDeploymentKey": fromDeploymentKey, + @"fromLabelOrAppVersion": fromLabel + }); + } else { + // Previous status report was with a binary app version. + resolve(@{ + @"appVersion": appVersion, + @"fromLabelOrAppVersion": previousStatusReportIdentifier + }); + } + return; } } diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index 8d7d64a..a7ee3b0 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -178,13 +178,10 @@ public class CodePush { } } - private String getPackageStatusReportIdentifier(WritableMap updatePackage) { - // Because deploymentKeys can be dynamically switched, we use a - // combination of the deploymentKey and label as the packageIdentifier. - String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY); - String label = CodePushUtils.tryGetString(updatePackage, LABEL_KEY); - if (deploymentKey != null && label != null) { - return deploymentKey + ":" + label; + private String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) { + String[] parsedIdentifier = statusReportIdentifier.split(":"); + if (parsedIdentifier.length > 0) { + return parsedIdentifier[0]; } else { return null; } @@ -208,6 +205,18 @@ public class CodePush { } } + private String getPackageStatusReportIdentifier(WritableMap updatePackage) { + // Because deploymentKeys can be dynamically switched, we use a + // combination of the deploymentKey and label as the packageIdentifier. + String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY); + String label = CodePushUtils.tryGetString(updatePackage, LABEL_KEY); + if (deploymentKey != null && label != null) { + return deploymentKey + ":" + label; + } else { + return null; + } + } + private JSONObject getPendingUpdate() { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); String pendingUpdateString = settings.getString(PENDING_UPDATE_KEY, null); @@ -226,6 +235,20 @@ public class CodePush { } } + private String getPreviousStatusReportIdentifier() { + SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); + return settings.getString(LAST_DEPLOYMENT_REPORT_KEY, null); + } + + private String getVersionLabelFromStatusReportIdentifier(String statusReportIdentifier) { + String[] parsedIdentifier = statusReportIdentifier.split(":"); + if (parsedIdentifier.length > 1) { + return parsedIdentifier[1]; + } else { + return null; + } + } + public ReactPackage getReactPackage() { if (codePushReactPackage == null) { codePushReactPackage = new CodePushReactPackage(); @@ -262,16 +285,6 @@ public class CodePush { } } - private boolean isDeploymentStatusNotYetReported(String appVersionOrPackageIdentifier) { - SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); - String lastDeploymentReportIdentifier = settings.getString(LAST_DEPLOYMENT_REPORT_KEY, null); - if (lastDeploymentReportIdentifier == null) { - return true; - } else { - return !lastDeploymentReportIdentifier.equals(appVersionOrPackageIdentifier); - } - } - private boolean isFailedHash(String packageHash) { JSONArray failedUpdates = getFailedUpdates(); if (packageHash != null) { @@ -306,6 +319,10 @@ public class CodePush { } } + private boolean isStatusReportIdentifierCodePushLabel(String statusReportIdentifier) { + return statusReportIdentifier != null && statusReportIdentifier.contains(":"); + } + private void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); settings.edit().putString(LAST_DEPLOYMENT_REPORT_KEY, appVersionOrPackageIdentifier).commit(); @@ -465,7 +482,8 @@ public class CodePush { JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1); WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON); String lastFailedPackageIdentifier = getPackageStatusReportIdentifier(lastFailedPackage); - if (lastFailedPackage != null && isDeploymentStatusNotYetReported(lastFailedPackageIdentifier)) { + String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); + if (lastFailedPackage != null && (previousStatusReportIdentifier == null || !previousStatusReportIdentifier.equals(lastFailedPackageIdentifier))) { recordDeploymentStatusReported(lastFailedPackageIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", lastFailedPackage); @@ -482,24 +500,65 @@ public class CodePush { WritableMap currentPackage = codePushPackage.getCurrentPackage(); if (currentPackage != null) { String currentPackageIdentifier = getPackageStatusReportIdentifier(currentPackage); - if (currentPackageIdentifier != null && isDeploymentStatusNotYetReported(currentPackageIdentifier)) { - recordDeploymentStatusReported(currentPackageIdentifier); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", currentPackage); - reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - promise.resolve(reportMap); - return; + String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); + if (currentPackageIdentifier != null) { + if (previousStatusReportIdentifier == null) { + recordDeploymentStatusReported(currentPackageIdentifier); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + promise.resolve(reportMap); + return; + } else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) { + recordDeploymentStatusReported(currentPackageIdentifier); + if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String fromDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String fromLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + reportMap.putString("fromDeploymentKey", fromDeploymentKey); + reportMap.putString("fromLabelOrAppVersion", fromLabel); + promise.resolve(reportMap); + } else { + // Previous status report was with a binary app version. + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + reportMap.putString("fromLabelOrAppVersion", previousStatusReportIdentifier); + promise.resolve(reportMap); + } + return; + } } } } else if (isRunningBinaryVersion) { // Check if the current appVersion has been reported. - String binaryIdentifier = "" + getBinaryResourcesModifiedTime(); - if (isDeploymentStatusNotYetReported(binaryIdentifier)) { - recordDeploymentStatusReported(binaryIdentifier); + String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); + if (previousStatusReportIdentifier == null) { + recordDeploymentStatusReported(appVersion); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putString("appVersion", appVersion); promise.resolve(reportMap); return; + } else if (!previousStatusReportIdentifier.equals(appVersion)) { + recordDeploymentStatusReported(appVersion); + if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String fromDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String fromLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putString("appVersion", appVersion); + reportMap.putString("fromDeploymentKey", fromDeploymentKey); + reportMap.putString("fromLabelOrAppVersion", fromLabel); + promise.resolve(reportMap); + } else { + // Previous status report was with a binary app version. + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putString("appVersion", appVersion); + reportMap.putString("fromLabelOrAppVersion", previousStatusReportIdentifier); + promise.resolve(reportMap); + } + return; } } diff --git a/package.json b/package.json index 38417f8..fa523d6 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "url": "https://github.com/Microsoft/react-native-code-push" }, "dependencies": { - "code-push": "1.5.1-beta", + "code-push": "1.5.2-beta", "semver": "^5.1.0" }, "devDependencies": { diff --git a/request-fetch-adapter.js b/request-fetch-adapter.js index eeeac81..abcf541 100644 --- a/request-fetch-adapter.js +++ b/request-fetch-adapter.js @@ -4,10 +4,11 @@ module.exports = { callback = requestBody; requestBody = null; } - - var headers = { + + const headers = { "Accept": "application/json", - "Content-Type": "application/json" + "Content-Type": "application/json", + "X-SDK-Version": getSDKVersion() }; if (requestBody && typeof requestBody === "object") { @@ -30,6 +31,10 @@ module.exports = { } }; +function getSDKVersion() { + return require("./package.json").dependencies["code-push"]; +} + function getHttpMethodName(verb) { // Note: This should stay in sync with the enum definition in // https://github.com/Microsoft/code-push/blob/master/sdk/script/acquisition-sdk.ts#L6 From bea2b9c1782eecd29a8c08160f9477b69574655b Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Tue, 26 Jan 2016 18:01:44 -0800 Subject: [PATCH 2/8] from -> previous --- CodePush.js | 12 +++++------ CodePush.m | 20 +++++++++---------- .../microsoft/codepush/react/CodePush.java | 20 +++++++++---------- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/CodePush.js b/CodePush.js index cfe8f3d..b95296a 100644 --- a/CodePush.js +++ b/CodePush.js @@ -103,9 +103,9 @@ function getPromisifiedSdk(requestFetchAdapter, config) { }); }; - sdk.reportStatusDeploy = (deployedPackage, status, fromLabelOrAppVersion, fromDeploymentKey) => { + sdk.reportStatusDeploy = (deployedPackage, status, previousLabelOrAppVersion, previousDeploymentKey) => { return new Promise((resolve, reject) => { - module.exports.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, fromLabelOrAppVersion, fromDeploymentKey, (err) => { + module.exports.AcquisitionSdk.prototype.reportStatusDeploy.call(sdk, deployedPackage, status, previousLabelOrAppVersion, previousDeploymentKey, (err) => { if (err) { reject(err); } else { @@ -140,15 +140,15 @@ async function notifyApplicationReady() { const statusReport = await NativeCodePush.getNewStatusReport(); if (statusReport) { const config = await getConfiguration(); - const fromLabelOrAppVersion = statusReport.fromLabelOrAppVersion; - const fromDeploymentKey = statusReport.fromDeploymentKey || config.deploymentKey; + const previousLabelOrAppVersion = statusReport.previousLabelOrAppVersion; + const previousDeploymentKey = statusReport.previousDeploymentKey || config.deploymentKey; if (statusReport.appVersion) { const sdk = getPromisifiedSdk(requestFetchAdapter, config); - sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, fromLabelOrAppVersion, fromDeploymentKey); + sdk.reportStatusDeploy(/* deployedPackage */ null, /* status */ null, previousLabelOrAppVersion, previousDeploymentKey); } else { config.deploymentKey = statusReport.package.deploymentKey; const sdk = getPromisifiedSdk(requestFetchAdapter, config); - sdk.reportStatusDeploy(statusReport.package, statusReport.status, fromLabelOrAppVersion, fromDeploymentKey); + sdk.reportStatusDeploy(statusReport.package, statusReport.status, previousLabelOrAppVersion, previousDeploymentKey); } } } diff --git a/CodePush.m b/CodePush.m index 1dd6d5f..8302357 100644 --- a/CodePush.m +++ b/CodePush.m @@ -586,20 +586,20 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { [self recordDeploymentStatusReported:currentPackageIdentifier]; if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *fromDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *fromLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; resolve(@{ @"package": currentPackage, @"status": DeploymentSucceeded, - @"fromDeploymentKey": fromDeploymentKey, - @"fromLabelOrAppVersion": fromLabel + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel }); } else { // Previous status report was with a binary app version. resolve(@{ @"package": currentPackage, @"status": DeploymentSucceeded, - @"fromLabelOrAppVersion": previousStatusReportIdentifier + @"previousLabelOrAppVersion": previousStatusReportIdentifier }); } return; @@ -617,18 +617,18 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { [self recordDeploymentStatusReported:appVersion]; if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *fromDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *fromLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; resolve(@{ @"appVersion": appVersion, - @"fromDeploymentKey": fromDeploymentKey, - @"fromLabelOrAppVersion": fromLabel + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel }); } else { // Previous status report was with a binary app version. resolve(@{ @"appVersion": appVersion, - @"fromLabelOrAppVersion": previousStatusReportIdentifier + @"previousLabelOrAppVersion": previousStatusReportIdentifier }); } return; diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index a7ee3b0..7405adb 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -512,20 +512,20 @@ public class CodePush { } else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) { recordDeploymentStatusReported(currentPackageIdentifier); if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String fromDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String fromLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", currentPackage); reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - reportMap.putString("fromDeploymentKey", fromDeploymentKey); - reportMap.putString("fromLabelOrAppVersion", fromLabel); + reportMap.putString("previousDeploymentKey", previousDeploymentKey); + reportMap.putString("previousLabelOrAppVersion", previousLabel); promise.resolve(reportMap); } else { // Previous status report was with a binary app version. WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", currentPackage); reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - reportMap.putString("fromLabelOrAppVersion", previousStatusReportIdentifier); + reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); promise.resolve(reportMap); } return; @@ -544,18 +544,18 @@ public class CodePush { } else if (!previousStatusReportIdentifier.equals(appVersion)) { recordDeploymentStatusReported(appVersion); if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String fromDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String fromLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putString("appVersion", appVersion); - reportMap.putString("fromDeploymentKey", fromDeploymentKey); - reportMap.putString("fromLabelOrAppVersion", fromLabel); + reportMap.putString("previousDeploymentKey", previousDeploymentKey); + reportMap.putString("previousLabelOrAppVersion", previousLabel); promise.resolve(reportMap); } else { // Previous status report was with a binary app version. WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putString("appVersion", appVersion); - reportMap.putString("fromLabelOrAppVersion", previousStatusReportIdentifier); + reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); promise.resolve(reportMap); } return; From 35539d15b453ea97e1138ce5d8eb466facac27fe Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Wed, 27 Jan 2016 00:23:02 -0800 Subject: [PATCH 3/8] feedback --- CodePush.h | 11 +++ CodePush.m | 86 ++++------------- CodePush.xcodeproj/project.pbxproj | 4 + CodePushStatusReport.m | 51 ++++++++++ .../microsoft/codepush/react/CodePush.java | 96 +++++-------------- .../codepush/react/CodePushStatusReport.java | 64 +++++++++++++ 6 files changed, 171 insertions(+), 141 deletions(-) create mode 100644 CodePushStatusReport.m create mode 100644 android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java diff --git a/CodePush.h b/CodePush.h index 428c81b..923a5e8 100644 --- a/CodePush.h +++ b/CodePush.h @@ -88,6 +88,17 @@ failCallback:(void (^)(NSError *err))failCallback; @end +@interface CodePushStatusReport : NSObject + ++ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier; ++ (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package; ++ (NSString *)getPreviousStatusReportIdentifier; ++ (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier; ++ (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier; ++ (void)recordDeploymentStatusReported:(NSString *)appVersionOrPackageIdentifier; + +@end + typedef NS_ENUM(NSInteger, CodePushInstallMode) { CodePushInstallModeImmediate, CodePushInstallModeOnNextRestart, diff --git a/CodePush.m b/CodePush.m index 8302357..5d84b40 100644 --- a/CodePush.m +++ b/CodePush.m @@ -23,7 +23,6 @@ static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; // These keys represent the names we use to store data in NSUserDefaults static NSString *const FailedUpdatesKey = @"CODE_PUSH_FAILED_UPDATES"; -static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT"; static NSString *const PendingUpdateKey = @"CODE_PUSH_PENDING_UPDATE"; // These keys are already "namespaced" by the PendingUpdateKey, so @@ -33,8 +32,6 @@ static NSString *const PendingUpdateIsLoadingKey = @"isLoading"; // These keys are used to inspect/augment the metadata // that is associated with an update's package. -static NSString *const DeploymentKeyKey = @"deploymentKey"; -static NSString *const LabelKey = @"label"; static NSString *const PackageHashKey = @"packageHash"; static NSString *const PackageIsPendingKey = @"isPending"; @@ -161,36 +158,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier -{ - return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; -} - -- (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package -{ - // Because deploymentKeys can be dynamically switched, we use a - // combination of the deploymentKey and label as the packageIdentifier. - NSString *deploymentKey = [package objectForKey:DeploymentKeyKey]; - NSString *label = [package objectForKey:LabelKey]; - if (deploymentKey && label) { - return [[deploymentKey stringByAppendingString:@":"] stringByAppendingString:label]; - } else { - return nil; - } -} - -- (NSString *)getPreviousStatusReportIdentifier -{ - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - NSString *sentStatusReportIdentifier = [preferences objectForKey:LastDeploymentReportKey]; - return sentStatusReportIdentifier; -} - -- (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier -{ - return [[statusReportIdentifier componentsSeparatedByString:@":"] lastObject]; -} - - (instancetype)init { self = [super init]; @@ -277,11 +244,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; return updateIsPending; } -- (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier -{ - return statusReportIdentifier != nil && [statusReportIdentifier containsString:@":"]; -} - /* * This method updates the React Native bridge's bundle URL * to point at the latest CodePush update, and then restarts @@ -304,13 +266,6 @@ static NSString *const PackageIsPendingKey = @"isPending"; }); } -- (void)recordDeploymentStatusReported:(NSString *)appVersionOrPackageIdentifier -{ - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - [preferences setValue:appVersionOrPackageIdentifier forKey:LastDeploymentReportKey]; - [preferences synchronize]; -} - /* * This method is used when an update has failed installation * and the app needs to be rolled back to the previous bundle. @@ -556,16 +511,11 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve if (failedUpdates) { NSDictionary *lastFailedPackage = [failedUpdates lastObject]; if (lastFailedPackage) { - NSString *lastFailedPackageIdentifier = [self getPackageStatusReportIdentifier:lastFailedPackage]; - NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; - if (lastFailedPackageIdentifier && (previousStatusReportIdentifier == nil || ![previousStatusReportIdentifier isEqualToString:lastFailedPackageIdentifier])) { - [self recordDeploymentStatusReported:lastFailedPackageIdentifier]; - resolve(@{ - @"package": lastFailedPackage, - @"status": DeploymentFailed - }); - return; - } + resolve(@{ + @"package": lastFailedPackage, + @"status": DeploymentFailed + }); + return; } } } else if (_isFirstRunAfterUpdate) { @@ -573,21 +523,21 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve NSError *error; NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; if (!error && currentPackage) { - NSString *currentPackageIdentifier = [self getPackageStatusReportIdentifier:currentPackage]; - NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + NSString *currentPackageIdentifier = [CodePushStatusReport getPackageStatusReportIdentifier:currentPackage]; + NSString *previousStatusReportIdentifier = [CodePushStatusReport getPreviousStatusReportIdentifier]; if (currentPackageIdentifier) { if (previousStatusReportIdentifier == nil) { - [self recordDeploymentStatusReported:currentPackageIdentifier]; + [CodePushStatusReport recordDeploymentStatusReported:currentPackageIdentifier]; resolve(@{ @"package": currentPackage, @"status": DeploymentSucceeded }); return; } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { - [self recordDeploymentStatusReported:currentPackageIdentifier]; - if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + [CodePushStatusReport recordDeploymentStatusReported:currentPackageIdentifier]; + if ([CodePushStatusReport isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *previousDeploymentKey = [CodePushStatusReport getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [CodePushStatusReport getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; resolve(@{ @"package": currentPackage, @"status": DeploymentSucceeded, @@ -609,16 +559,16 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { // Check if the current appVersion has been reported. NSString *appVersion = [[CodePushConfig current] appVersion]; - NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + NSString *previousStatusReportIdentifier = [CodePushStatusReport getPreviousStatusReportIdentifier]; if (previousStatusReportIdentifier == nil) { - [self recordDeploymentStatusReported:appVersion]; + [CodePushStatusReport recordDeploymentStatusReported:appVersion]; resolve(@{ @"appVersion": appVersion }); return; } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { - [self recordDeploymentStatusReported:appVersion]; - if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + [CodePushStatusReport recordDeploymentStatusReported:appVersion]; + if ([CodePushStatusReport isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *previousDeploymentKey = [CodePushStatusReport getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [CodePushStatusReport getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; resolve(@{ @"appVersion": appVersion, @"previousDeploymentKey": previousDeploymentKey, diff --git a/CodePush.xcodeproj/project.pbxproj b/CodePush.xcodeproj/project.pbxproj index 6961441..72846f0 100644 --- a/CodePush.xcodeproj/project.pbxproj +++ b/CodePush.xcodeproj/project.pbxproj @@ -9,6 +9,7 @@ /* Begin PBXBuildFile section */ 13BE3DEE1AC21097009241FE /* CodePush.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.m */; }; 1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */; }; + 5421FE311C58AD5A00986A55 /* CodePushStatusReport.m in Sources */ = {isa = PBXBuildFile; fileRef = 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */; }; 54A0026C1C0E2880004C3CEC /* aescrypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024C1C0E2880004C3CEC /* aescrypt.c */; }; 54A0026D1C0E2880004C3CEC /* aeskey.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024D1C0E2880004C3CEC /* aeskey.c */; }; 54A0026E1C0E2880004C3CEC /* aestab.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024F1C0E2880004C3CEC /* aestab.c */; }; @@ -45,6 +46,7 @@ 13BE3DEC1AC21097009241FE /* CodePush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodePush.h; sourceTree = ""; }; 13BE3DED1AC21097009241FE /* CodePush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePush.m; sourceTree = ""; }; 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CodePushInstallMode.m"; sourceTree = ""; }; + 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushStatusReport.m; sourceTree = ""; }; 54A0024A1C0E2880004C3CEC /* aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes.h; sourceTree = ""; }; 54A0024B1C0E2880004C3CEC /* aes_via_ace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes_via_ace.h; sourceTree = ""; }; 54A0024C1C0E2880004C3CEC /* aescrypt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aescrypt.c; sourceTree = ""; }; @@ -165,6 +167,7 @@ 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */, 54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */, 810D4E6C1B96935000B397E9 /* CodePushPackage.m */, + 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */, 81D51F391B6181C2000DA084 /* CodePushConfig.m */, 13BE3DEC1AC21097009241FE /* CodePush.h */, 13BE3DED1AC21097009241FE /* CodePush.m */, @@ -239,6 +242,7 @@ 54FFEDE01BF550630061DD23 /* CodePushDownloadHandler.m in Sources */, 54A002711C0E2880004C3CEC /* hmac.c in Sources */, 54A002721C0E2880004C3CEC /* prng.c in Sources */, + 5421FE311C58AD5A00986A55 /* CodePushStatusReport.m in Sources */, 54A002731C0E2880004C3CEC /* pwd2key.c in Sources */, 54A002751C0E2880004C3CEC /* ioapi.c in Sources */, 54A002771C0E2880004C3CEC /* unzip.c in Sources */, diff --git a/CodePushStatusReport.m b/CodePushStatusReport.m new file mode 100644 index 0000000..fcd8a39 --- /dev/null +++ b/CodePushStatusReport.m @@ -0,0 +1,51 @@ +#import "CodePush.h" + +static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT"; +static NSString *const DeploymentKeyKey = @"deploymentKey"; +static NSString *const LabelKey = @"label"; + +@implementation CodePushStatusReport + ++ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier +{ + return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; +} + ++ (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package +{ + // Because deploymentKeys can be dynamically switched, we use a + // combination of the deploymentKey and label as the packageIdentifier. + NSString *deploymentKey = [package objectForKey:DeploymentKeyKey]; + NSString *label = [package objectForKey:LabelKey]; + if (deploymentKey && label) { + return [[deploymentKey stringByAppendingString:@":"] stringByAppendingString:label]; + } else { + return nil; + } +} + ++ (NSString *)getPreviousStatusReportIdentifier +{ + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + NSString *sentStatusReportIdentifier = [preferences objectForKey:LastDeploymentReportKey]; + return sentStatusReportIdentifier; +} + ++ (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier +{ + return [[statusReportIdentifier componentsSeparatedByString:@":"] lastObject]; +} + ++ (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier +{ + return statusReportIdentifier != nil && [statusReportIdentifier containsString:@":"]; +} + ++ (void)recordDeploymentStatusReported:(NSString *)appVersionOrPackageIdentifier +{ + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + [preferences setValue:appVersionOrPackageIdentifier forKey:LastDeploymentReportKey]; + [preferences synchronize]; +} + +@end \ No newline at end of file diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index 7405adb..b2e9801 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -52,23 +52,22 @@ public class CodePush { private final String BINARY_MODIFIED_TIME_KEY = "binaryModifiedTime"; private final String CODE_PUSH_PREFERENCES = "CodePush"; private final String DEPLOYMENT_FAILED_STATUS = "DeploymentFailed"; - private final String DEPLOYMENT_KEY_KEY = "deploymentKey"; private final String DEPLOYMENT_SUCCEEDED_STATUS = "DeploymentSucceeded"; private final String DOWNLOAD_PROGRESS_EVENT_NAME = "CodePushDownloadProgress"; private final String FAILED_UPDATES_KEY = "CODE_PUSH_FAILED_UPDATES"; - private final String LABEL_KEY = "label"; private final String PACKAGE_HASH_KEY = "packageHash"; private final String PENDING_UPDATE_HASH_KEY = "hash"; private final String PENDING_UPDATE_IS_LOADING_KEY = "isLoading"; private final String PENDING_UPDATE_KEY = "CODE_PUSH_PENDING_UPDATE"; private final String RESOURCES_BUNDLE = "resources.arsc"; - private final String LAST_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_LAST_DEPLOYMENT_REPORT"; // This needs to be kept in sync with https://github.com/facebook/react-native/blob/master/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManager.java#L78 private final String REACT_DEV_BUNDLE_CACHE_FILE_NAME = "ReactNativeDevBundle.js"; + // Helper classes. private CodePushPackage codePushPackage; private CodePushReactPackage codePushReactPackage; + private CodePushStatusReport codePushStatusReport; private CodePushNativeModule codePushNativeModule; // Config properties. @@ -87,12 +86,12 @@ public class CodePush { public CodePush(String deploymentKey, Activity mainActivity, boolean isDebugMode) { SoLoader.init(mainActivity, false); - this.deploymentKey = deploymentKey; - this.codePushPackage = new CodePushPackage(mainActivity.getFilesDir().getAbsolutePath()); - this.mainActivity = mainActivity; this.applicationContext = mainActivity.getApplicationContext(); + this.codePushPackage = new CodePushPackage(mainActivity.getFilesDir().getAbsolutePath()); + this.codePushStatusReport = new CodePushStatusReport(this.applicationContext, CODE_PUSH_PREFERENCES); this.deploymentKey = deploymentKey; this.isDebugMode = isDebugMode; + this.mainActivity = mainActivity; PackageInfo pInfo = null; try { @@ -178,15 +177,6 @@ public class CodePush { } } - private String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) { - String[] parsedIdentifier = statusReportIdentifier.split(":"); - if (parsedIdentifier.length > 0) { - return parsedIdentifier[0]; - } else { - return null; - } - } - private JSONArray getFailedUpdates() { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); String failedUpdatesString = settings.getString(FAILED_UPDATES_KEY, null); @@ -205,18 +195,6 @@ public class CodePush { } } - private String getPackageStatusReportIdentifier(WritableMap updatePackage) { - // Because deploymentKeys can be dynamically switched, we use a - // combination of the deploymentKey and label as the packageIdentifier. - String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY); - String label = CodePushUtils.tryGetString(updatePackage, LABEL_KEY); - if (deploymentKey != null && label != null) { - return deploymentKey + ":" + label; - } else { - return null; - } - } - private JSONObject getPendingUpdate() { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); String pendingUpdateString = settings.getString(PENDING_UPDATE_KEY, null); @@ -235,20 +213,6 @@ public class CodePush { } } - private String getPreviousStatusReportIdentifier() { - SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); - return settings.getString(LAST_DEPLOYMENT_REPORT_KEY, null); - } - - private String getVersionLabelFromStatusReportIdentifier(String statusReportIdentifier) { - String[] parsedIdentifier = statusReportIdentifier.split(":"); - if (parsedIdentifier.length > 1) { - return parsedIdentifier[1]; - } else { - return null; - } - } - public ReactPackage getReactPackage() { if (codePushReactPackage == null) { codePushReactPackage = new CodePushReactPackage(); @@ -319,15 +283,6 @@ public class CodePush { } } - private boolean isStatusReportIdentifierCodePushLabel(String statusReportIdentifier) { - return statusReportIdentifier != null && statusReportIdentifier.contains(":"); - } - - private void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) { - SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); - settings.edit().putString(LAST_DEPLOYMENT_REPORT_KEY, appVersionOrPackageIdentifier).commit(); - } - private void removeFailedUpdates() { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); settings.edit().remove(FAILED_UPDATES_KEY).commit(); @@ -481,16 +436,11 @@ public class CodePush { try { JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1); WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON); - String lastFailedPackageIdentifier = getPackageStatusReportIdentifier(lastFailedPackage); - String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); - if (lastFailedPackage != null && (previousStatusReportIdentifier == null || !previousStatusReportIdentifier.equals(lastFailedPackageIdentifier))) { - recordDeploymentStatusReported(lastFailedPackageIdentifier); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", lastFailedPackage); - reportMap.putString("status", DEPLOYMENT_FAILED_STATUS); - promise.resolve(reportMap); - return; - } + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", lastFailedPackage); + reportMap.putString("status", DEPLOYMENT_FAILED_STATUS); + promise.resolve(reportMap); + return; } catch (JSONException e) { throw new CodePushUnknownException("Unable to read failed updates information stored in SharedPreferences.", e); } @@ -499,21 +449,21 @@ public class CodePush { // Check if the current CodePush package has been reported WritableMap currentPackage = codePushPackage.getCurrentPackage(); if (currentPackage != null) { - String currentPackageIdentifier = getPackageStatusReportIdentifier(currentPackage); - String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); + String currentPackageIdentifier = codePushStatusReport.getPackageStatusReportIdentifier(currentPackage); + String previousStatusReportIdentifier = codePushStatusReport.getPreviousStatusReportIdentifier(); if (currentPackageIdentifier != null) { if (previousStatusReportIdentifier == null) { - recordDeploymentStatusReported(currentPackageIdentifier); + codePushStatusReport.recordDeploymentStatusReported(currentPackageIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", currentPackage); reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); promise.resolve(reportMap); return; } else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) { - recordDeploymentStatusReported(currentPackageIdentifier); - if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String previousDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String previousLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + codePushStatusReport.recordDeploymentStatusReported(currentPackageIdentifier); + if (codePushStatusReport.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String previousDeploymentKey = codePushStatusReport.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = codePushStatusReport.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", currentPackage); reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); @@ -534,18 +484,18 @@ public class CodePush { } } else if (isRunningBinaryVersion) { // Check if the current appVersion has been reported. - String previousStatusReportIdentifier = getPreviousStatusReportIdentifier(); + String previousStatusReportIdentifier = codePushStatusReport.getPreviousStatusReportIdentifier(); if (previousStatusReportIdentifier == null) { - recordDeploymentStatusReported(appVersion); + codePushStatusReport.recordDeploymentStatusReported(appVersion); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putString("appVersion", appVersion); promise.resolve(reportMap); return; } else if (!previousStatusReportIdentifier.equals(appVersion)) { - recordDeploymentStatusReported(appVersion); - if (isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String previousDeploymentKey = getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String previousLabel = getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + codePushStatusReport.recordDeploymentStatusReported(appVersion); + if (codePushStatusReport.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String previousDeploymentKey = codePushStatusReport.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = codePushStatusReport.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putString("appVersion", appVersion); reportMap.putString("previousDeploymentKey", previousDeploymentKey); diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java new file mode 100644 index 0000000..3dd9d0f --- /dev/null +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java @@ -0,0 +1,64 @@ +package com.microsoft.codepush.react; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.facebook.react.bridge.WritableMap; + +public class CodePushStatusReport { + + private Context applicationContext; + private final String CODE_PUSH_PREFERENCES; + private final String DEPLOYMENT_KEY_KEY = "deploymentKey"; + private final String LABEL_KEY = "label"; + private final String LAST_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_LAST_DEPLOYMENT_REPORT"; + + public CodePushStatusReport(Context applicationContext, String codePushPreferencesKey) { + this.applicationContext = applicationContext; + this.CODE_PUSH_PREFERENCES = codePushPreferencesKey; + } + + public String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) { + String[] parsedIdentifier = statusReportIdentifier.split(":"); + if (parsedIdentifier.length > 0) { + return parsedIdentifier[0]; + } else { + return null; + } + } + + public String getPackageStatusReportIdentifier(WritableMap updatePackage) { + // Because deploymentKeys can be dynamically switched, we use a + // combination of the deploymentKey and label as the packageIdentifier. + String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY); + String label = CodePushUtils.tryGetString(updatePackage, LABEL_KEY); + if (deploymentKey != null && label != null) { + return deploymentKey + ":" + label; + } else { + return null; + } + } + + public String getPreviousStatusReportIdentifier() { + SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); + return settings.getString(LAST_DEPLOYMENT_REPORT_KEY, null); + } + + public String getVersionLabelFromStatusReportIdentifier(String statusReportIdentifier) { + String[] parsedIdentifier = statusReportIdentifier.split(":"); + if (parsedIdentifier.length > 1) { + return parsedIdentifier[1]; + } else { + return null; + } + } + + public boolean isStatusReportIdentifierCodePushLabel(String statusReportIdentifier) { + return statusReportIdentifier != null && statusReportIdentifier.contains(":"); + } + + public void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) { + SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); + settings.edit().putString(LAST_DEPLOYMENT_REPORT_KEY, appVersionOrPackageIdentifier).commit(); + } +} From eb44af2497e2a90b9b9bf452ef27381a03d872ee Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Wed, 27 Jan 2016 00:26:46 -0800 Subject: [PATCH 4/8] X-CodePush-SDK-Version --- request-fetch-adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/request-fetch-adapter.js b/request-fetch-adapter.js index abcf541..4aef90e 100644 --- a/request-fetch-adapter.js +++ b/request-fetch-adapter.js @@ -8,7 +8,7 @@ module.exports = { const headers = { "Accept": "application/json", "Content-Type": "application/json", - "X-SDK-Version": getSDKVersion() + "X-CodePush-SDK-Version": getSDKVersion() }; if (requestBody && typeof requestBody === "object") { From 0500545235c9825bbce015cd90ac9cb0a43994ef Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Wed, 27 Jan 2016 16:13:00 -0800 Subject: [PATCH 5/8] refactor getNewStatusReport --- CodePush.h | 3 + CodePush.m | 71 ++--------------- CodePushStatusReport.m | 76 +++++++++++++++++- .../microsoft/codepush/react/CodePush.java | 77 +++---------------- .../codepush/react/CodePushStatusReport.java | 72 +++++++++++++++++ 5 files changed, 170 insertions(+), 129 deletions(-) diff --git a/CodePush.h b/CodePush.h index 923a5e8..99e6e61 100644 --- a/CodePush.h +++ b/CodePush.h @@ -91,6 +91,9 @@ failCallback:(void (^)(NSError *err))failCallback; @interface CodePushStatusReport : NSObject + (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier; ++ (NSDictionary *)getFailedUpdateStatusReport:(NSDictionary *)lastFailedPackage; ++ (NSDictionary *)getNewPackageStatusReport:(NSDictionary *)currentPackage; ++ (NSDictionary *)getNewAppVersionStatusReport:(NSString *)appVersion; + (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package; + (NSString *)getPreviousStatusReportIdentifier; + (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier; diff --git a/CodePush.m b/CodePush.m index 5d84b40..35b424f 100644 --- a/CodePush.m +++ b/CodePush.m @@ -493,11 +493,11 @@ RCT_EXPORT_METHOD(notifyApplicationReady:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { [CodePush removePendingUpdate]; - resolve([NSNull null]); + resolve(nil); } /* - * This method is checks if a new status update exists (new version was installed, + * This method is checks if a new status update exists (new version was installed, * or an update failed) and return its details (version label, status). */ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve @@ -511,10 +511,7 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve if (failedUpdates) { NSDictionary *lastFailedPackage = [failedUpdates lastObject]; if (lastFailedPackage) { - resolve(@{ - @"package": lastFailedPackage, - @"status": DeploymentFailed - }); + resolve([CodePushStatusReport getFailedUpdateStatusReport:lastFailedPackage]); return; } } @@ -523,69 +520,17 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve NSError *error; NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; if (!error && currentPackage) { - NSString *currentPackageIdentifier = [CodePushStatusReport getPackageStatusReportIdentifier:currentPackage]; - NSString *previousStatusReportIdentifier = [CodePushStatusReport getPreviousStatusReportIdentifier]; - if (currentPackageIdentifier) { - if (previousStatusReportIdentifier == nil) { - [CodePushStatusReport recordDeploymentStatusReported:currentPackageIdentifier]; - resolve(@{ - @"package": currentPackage, - @"status": DeploymentSucceeded - }); - return; - } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { - [CodePushStatusReport recordDeploymentStatusReported:currentPackageIdentifier]; - if ([CodePushStatusReport isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *previousDeploymentKey = [CodePushStatusReport getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *previousLabel = [CodePushStatusReport getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; - resolve(@{ - @"package": currentPackage, - @"status": DeploymentSucceeded, - @"previousDeploymentKey": previousDeploymentKey, - @"previousLabelOrAppVersion": previousLabel - }); - } else { - // Previous status report was with a binary app version. - resolve(@{ - @"package": currentPackage, - @"status": DeploymentSucceeded, - @"previousLabelOrAppVersion": previousStatusReportIdentifier - }); - } - return; - } - } + resolve([CodePushStatusReport getNewPackageStatusReport:currentPackage]); + return; } } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { // Check if the current appVersion has been reported. NSString *appVersion = [[CodePushConfig current] appVersion]; - NSString *previousStatusReportIdentifier = [CodePushStatusReport getPreviousStatusReportIdentifier]; - if (previousStatusReportIdentifier == nil) { - [CodePushStatusReport recordDeploymentStatusReported:appVersion]; - resolve(@{ @"appVersion": appVersion }); - return; - } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { - [CodePushStatusReport recordDeploymentStatusReported:appVersion]; - if ([CodePushStatusReport isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *previousDeploymentKey = [CodePushStatusReport getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *previousLabel = [CodePushStatusReport getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; - resolve(@{ - @"appVersion": appVersion, - @"previousDeploymentKey": previousDeploymentKey, - @"previousLabelOrAppVersion": previousLabel - }); - } else { - // Previous status report was with a binary app version. - resolve(@{ - @"appVersion": appVersion, - @"previousLabelOrAppVersion": previousStatusReportIdentifier - }); - } - return; - } + resolve([CodePushStatusReport getNewAppVersionStatusReport:appVersion]); + return; } - resolve([NSNull null]); + resolve(nil); } /* diff --git a/CodePushStatusReport.m b/CodePushStatusReport.m index fcd8a39..f4f4096 100644 --- a/CodePushStatusReport.m +++ b/CodePushStatusReport.m @@ -1,8 +1,10 @@ #import "CodePush.h" -static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT"; +static NSString *const DeploymentFailed = @"DeploymentFailed"; static NSString *const DeploymentKeyKey = @"deploymentKey"; +static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; static NSString *const LabelKey = @"label"; +static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT"; @implementation CodePushStatusReport @@ -11,6 +13,78 @@ static NSString *const LabelKey = @"label"; return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; } ++ (NSDictionary *)getFailedUpdateStatusReport:(NSDictionary *)lastFailedPackage +{ + return @{ + @"package": lastFailedPackage, + @"status": DeploymentFailed + }; +} + ++ (NSDictionary *)getNewPackageStatusReport:(NSDictionary *)currentPackage +{ + NSString *currentPackageIdentifier = [self getPackageStatusReportIdentifier:currentPackage]; + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (currentPackageIdentifier) { + if (previousStatusReportIdentifier == nil) { + [self recordDeploymentStatusReported:currentPackageIdentifier]; + return @{ + @"package": currentPackage, + @"status": DeploymentSucceeded + }; + } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { + [self recordDeploymentStatusReported:currentPackageIdentifier]; + if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + return @{ + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel + }; + } else { + // Previous status report was with a binary app version. + return @{ + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"previousLabelOrAppVersion": previousStatusReportIdentifier + }; + } + } + } + + return nil; +} + ++ (NSDictionary *)getNewAppVersionStatusReport:(NSString *)appVersion +{ + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (previousStatusReportIdentifier == nil) { + [self recordDeploymentStatusReported:appVersion]; + return @{ @"appVersion": appVersion }; + } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { + [self recordDeploymentStatusReported:appVersion]; + if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + return @{ + @"appVersion": appVersion, + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel + }; + } else { + // Previous status report was with a binary app version. + return @{ + @"appVersion": appVersion, + @"previousLabelOrAppVersion": previousStatusReportIdentifier + }; + } + } + + return nil; +} + + (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package { // Because deploymentKeys can be dynamically switched, we use a diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index b2e9801..426b3c5 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -51,8 +51,6 @@ public class CodePush { private final String ASSETS_BUNDLE_PREFIX = "assets://"; private final String BINARY_MODIFIED_TIME_KEY = "binaryModifiedTime"; private final String CODE_PUSH_PREFERENCES = "CodePush"; - private final String DEPLOYMENT_FAILED_STATUS = "DeploymentFailed"; - private final String DEPLOYMENT_SUCCEEDED_STATUS = "DeploymentSucceeded"; private final String DOWNLOAD_PROGRESS_EVENT_NAME = "CodePushDownloadProgress"; private final String FAILED_UPDATES_KEY = "CODE_PUSH_FAILED_UPDATES"; private final String PACKAGE_HASH_KEY = "packageHash"; @@ -429,85 +427,34 @@ public class CodePush { @ReactMethod public void getNewStatusReport(Promise promise) { if (needToReportRollback) { - // Check if there was a rollback that was not yet reported needToReportRollback = false; JSONArray failedUpdates = getFailedUpdates(); if (failedUpdates != null && failedUpdates.length() > 0) { try { JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1); WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", lastFailedPackage); - reportMap.putString("status", DEPLOYMENT_FAILED_STATUS); - promise.resolve(reportMap); - return; + WritableMap failedStatusReport = codePushStatusReport.getFailedUpdateStatusReport(lastFailedPackage); + if (failedStatusReport != null) { + promise.resolve(failedStatusReport); + return; + } } catch (JSONException e) { throw new CodePushUnknownException("Unable to read failed updates information stored in SharedPreferences.", e); } } } else if (didUpdate) { - // Check if the current CodePush package has been reported WritableMap currentPackage = codePushPackage.getCurrentPackage(); if (currentPackage != null) { - String currentPackageIdentifier = codePushStatusReport.getPackageStatusReportIdentifier(currentPackage); - String previousStatusReportIdentifier = codePushStatusReport.getPreviousStatusReportIdentifier(); - if (currentPackageIdentifier != null) { - if (previousStatusReportIdentifier == null) { - codePushStatusReport.recordDeploymentStatusReported(currentPackageIdentifier); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", currentPackage); - reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - promise.resolve(reportMap); - return; - } else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) { - codePushStatusReport.recordDeploymentStatusReported(currentPackageIdentifier); - if (codePushStatusReport.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String previousDeploymentKey = codePushStatusReport.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String previousLabel = codePushStatusReport.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", currentPackage); - reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - reportMap.putString("previousDeploymentKey", previousDeploymentKey); - reportMap.putString("previousLabelOrAppVersion", previousLabel); - promise.resolve(reportMap); - } else { - // Previous status report was with a binary app version. - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putMap("package", currentPackage); - reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); - reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); - promise.resolve(reportMap); - } - return; - } + WritableMap newPackageStatusReport = codePushStatusReport.getNewPackageStatusReport(currentPackage); + if (newPackageStatusReport != null) { + promise.resolve(newPackageStatusReport); + return; } } } else if (isRunningBinaryVersion) { - // Check if the current appVersion has been reported. - String previousStatusReportIdentifier = codePushStatusReport.getPreviousStatusReportIdentifier(); - if (previousStatusReportIdentifier == null) { - codePushStatusReport.recordDeploymentStatusReported(appVersion); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putString("appVersion", appVersion); - promise.resolve(reportMap); - return; - } else if (!previousStatusReportIdentifier.equals(appVersion)) { - codePushStatusReport.recordDeploymentStatusReported(appVersion); - if (codePushStatusReport.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String previousDeploymentKey = codePushStatusReport.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String previousLabel = codePushStatusReport.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putString("appVersion", appVersion); - reportMap.putString("previousDeploymentKey", previousDeploymentKey); - reportMap.putString("previousLabelOrAppVersion", previousLabel); - promise.resolve(reportMap); - } else { - // Previous status report was with a binary app version. - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putString("appVersion", appVersion); - reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); - promise.resolve(reportMap); - } + WritableMap newAppVersionStatusReport = codePushStatusReport.getNewAppVersionStatusReport(appVersion); + if (newAppVersionStatusReport != null) { + promise.resolve(newAppVersionStatusReport); return; } } diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java index 3dd9d0f..d3ffc76 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java @@ -4,12 +4,15 @@ import android.content.Context; import android.content.SharedPreferences; import com.facebook.react.bridge.WritableMap; +import com.facebook.react.bridge.WritableNativeMap; public class CodePushStatusReport { private Context applicationContext; private final String CODE_PUSH_PREFERENCES; + private final String DEPLOYMENT_FAILED_STATUS = "DeploymentFailed"; private final String DEPLOYMENT_KEY_KEY = "deploymentKey"; + private final String DEPLOYMENT_SUCCEEDED_STATUS = "DeploymentSucceeded"; private final String LABEL_KEY = "label"; private final String LAST_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_LAST_DEPLOYMENT_REPORT"; @@ -27,6 +30,75 @@ public class CodePushStatusReport { } } + public WritableMap getFailedUpdateStatusReport(WritableMap lastFailedPackage) { + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", lastFailedPackage); + reportMap.putString("status", DEPLOYMENT_FAILED_STATUS); + return reportMap; + } + + public WritableMap getNewPackageStatusReport(WritableMap currentPackage) { + String currentPackageIdentifier = this.getPackageStatusReportIdentifier(currentPackage); + String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier(); + if (currentPackageIdentifier != null) { + if (previousStatusReportIdentifier == null) { + this.recordDeploymentStatusReported(currentPackageIdentifier); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + return reportMap; + } else if (!previousStatusReportIdentifier.equals(currentPackageIdentifier)) { + this.recordDeploymentStatusReported(currentPackageIdentifier); + if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + reportMap.putString("previousDeploymentKey", previousDeploymentKey); + reportMap.putString("previousLabelOrAppVersion", previousLabel); + return reportMap; + } else { + // Previous status report was with a binary app version. + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putMap("package", currentPackage); + reportMap.putString("status", DEPLOYMENT_SUCCEEDED_STATUS); + reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); + return reportMap; + } + } + } + + return null; + } + + public WritableMap getNewAppVersionStatusReport(String appVersion) { + String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier(); + if (previousStatusReportIdentifier == null) { + this.recordDeploymentStatusReported(appVersion); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putString("appVersion", appVersion); + return reportMap; + } else if (!previousStatusReportIdentifier.equals(appVersion)) { + this.recordDeploymentStatusReported(appVersion); + WritableNativeMap reportMap = new WritableNativeMap(); + if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + reportMap.putString("appVersion", appVersion); + reportMap.putString("previousDeploymentKey", previousDeploymentKey); + reportMap.putString("previousLabelOrAppVersion", previousLabel); + } else { + // Previous status report was with a binary app version. + reportMap.putString("appVersion", appVersion); + reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); + } + return reportMap; + } + + return null; + } + public String getPackageStatusReportIdentifier(WritableMap updatePackage) { // Because deploymentKeys can be dynamically switched, we use a // combination of the deploymentKey and label as the packageIdentifier. From 03ba1ed20eaf4547ea88ca8810f19efe7ffe91be Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Wed, 27 Jan 2016 18:05:35 -0800 Subject: [PATCH 6/8] CodePushStatusReport -> CodePushTelemetryManager --- CodePush.h | 14 +--- CodePush.m | 8 +- CodePush.xcodeproj/project.pbxproj | 8 +- ...atusReport.m => CodePushTelemetryManager.m | 60 +++++++------- .../microsoft/codepush/react/CodePush.java | 10 +-- ...ort.java => CodePushTelemetryManager.java} | 78 +++++++++---------- request-fetch-adapter.js | 2 +- 7 files changed, 86 insertions(+), 94 deletions(-) rename CodePushStatusReport.m => CodePushTelemetryManager.m (94%) rename android/app/src/main/java/com/microsoft/codepush/react/{CodePushStatusReport.java => CodePushTelemetryManager.java} (87%) diff --git a/CodePush.h b/CodePush.h index 99e6e61..7704421 100644 --- a/CodePush.h +++ b/CodePush.h @@ -88,17 +88,11 @@ failCallback:(void (^)(NSError *err))failCallback; @end -@interface CodePushStatusReport : NSObject +@interface CodePushTelemetryManager : NSObject -+ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier; -+ (NSDictionary *)getFailedUpdateStatusReport:(NSDictionary *)lastFailedPackage; -+ (NSDictionary *)getNewPackageStatusReport:(NSDictionary *)currentPackage; -+ (NSDictionary *)getNewAppVersionStatusReport:(NSString *)appVersion; -+ (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package; -+ (NSString *)getPreviousStatusReportIdentifier; -+ (NSString *)getVersionLabelFromStatusReportIdentifier:(NSString *)statusReportIdentifier; -+ (BOOL)isStatusReportIdentifierCodePushLabel:(NSString *)statusReportIdentifier; -+ (void)recordDeploymentStatusReported:(NSString *)appVersionOrPackageIdentifier; ++ (NSDictionary *)getBinaryUpdateReport:(NSString *)appVersion; ++ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage; ++ (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage; @end diff --git a/CodePush.m b/CodePush.m index 35b424f..933621d 100644 --- a/CodePush.m +++ b/CodePush.m @@ -504,29 +504,27 @@ RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { if (needToReportRollback) { - // Check if there was a rollback that was not yet reported needToReportRollback = NO; NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; NSMutableArray *failedUpdates = [preferences objectForKey:FailedUpdatesKey]; if (failedUpdates) { NSDictionary *lastFailedPackage = [failedUpdates lastObject]; if (lastFailedPackage) { - resolve([CodePushStatusReport getFailedUpdateStatusReport:lastFailedPackage]); + resolve([CodePushTelemetryManager getRollbackReport:lastFailedPackage]); return; } } } else if (_isFirstRunAfterUpdate) { - // Check if the current CodePush package has been reported NSError *error; NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; if (!error && currentPackage) { - resolve([CodePushStatusReport getNewPackageStatusReport:currentPackage]); + resolve([CodePushTelemetryManager getUpdateReport:currentPackage]); return; } } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { // Check if the current appVersion has been reported. NSString *appVersion = [[CodePushConfig current] appVersion]; - resolve([CodePushStatusReport getNewAppVersionStatusReport:appVersion]); + resolve([CodePushTelemetryManager getBinaryUpdateReport:appVersion]); return; } diff --git a/CodePush.xcodeproj/project.pbxproj b/CodePush.xcodeproj/project.pbxproj index 72846f0..d3c086c 100644 --- a/CodePush.xcodeproj/project.pbxproj +++ b/CodePush.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 13BE3DEE1AC21097009241FE /* CodePush.m in Sources */ = {isa = PBXBuildFile; fileRef = 13BE3DED1AC21097009241FE /* CodePush.m */; }; 1B23B9141BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */; }; - 5421FE311C58AD5A00986A55 /* CodePushStatusReport.m in Sources */ = {isa = PBXBuildFile; fileRef = 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */; }; + 5421FE311C58AD5A00986A55 /* CodePushTelemetryManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 5421FE301C58AD5A00986A55 /* CodePushTelemetryManager.m */; }; 54A0026C1C0E2880004C3CEC /* aescrypt.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024C1C0E2880004C3CEC /* aescrypt.c */; }; 54A0026D1C0E2880004C3CEC /* aeskey.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024D1C0E2880004C3CEC /* aeskey.c */; }; 54A0026E1C0E2880004C3CEC /* aestab.c in Sources */ = {isa = PBXBuildFile; fileRef = 54A0024F1C0E2880004C3CEC /* aestab.c */; }; @@ -46,7 +46,7 @@ 13BE3DEC1AC21097009241FE /* CodePush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CodePush.h; sourceTree = ""; }; 13BE3DED1AC21097009241FE /* CodePush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePush.m; sourceTree = ""; }; 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+CodePushInstallMode.m"; sourceTree = ""; }; - 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushStatusReport.m; sourceTree = ""; }; + 5421FE301C58AD5A00986A55 /* CodePushTelemetryManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CodePushTelemetryManager.m; sourceTree = ""; }; 54A0024A1C0E2880004C3CEC /* aes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes.h; sourceTree = ""; }; 54A0024B1C0E2880004C3CEC /* aes_via_ace.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aes_via_ace.h; sourceTree = ""; }; 54A0024C1C0E2880004C3CEC /* aescrypt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aescrypt.c; sourceTree = ""; }; @@ -167,7 +167,7 @@ 1B23B9131BF9267B000BB2F0 /* RCTConvert+CodePushInstallMode.m */, 54FFEDDF1BF550630061DD23 /* CodePushDownloadHandler.m */, 810D4E6C1B96935000B397E9 /* CodePushPackage.m */, - 5421FE301C58AD5A00986A55 /* CodePushStatusReport.m */, + 5421FE301C58AD5A00986A55 /* CodePushTelemetryManager.m */, 81D51F391B6181C2000DA084 /* CodePushConfig.m */, 13BE3DEC1AC21097009241FE /* CodePush.h */, 13BE3DED1AC21097009241FE /* CodePush.m */, @@ -242,7 +242,7 @@ 54FFEDE01BF550630061DD23 /* CodePushDownloadHandler.m in Sources */, 54A002711C0E2880004C3CEC /* hmac.c in Sources */, 54A002721C0E2880004C3CEC /* prng.c in Sources */, - 5421FE311C58AD5A00986A55 /* CodePushStatusReport.m in Sources */, + 5421FE311C58AD5A00986A55 /* CodePushTelemetryManager.m in Sources */, 54A002731C0E2880004C3CEC /* pwd2key.c in Sources */, 54A002751C0E2880004C3CEC /* ioapi.c in Sources */, 54A002771C0E2880004C3CEC /* unzip.c in Sources */, diff --git a/CodePushStatusReport.m b/CodePushTelemetryManager.m similarity index 94% rename from CodePushStatusReport.m rename to CodePushTelemetryManager.m index f4f4096..6c5194e 100644 --- a/CodePushStatusReport.m +++ b/CodePushTelemetryManager.m @@ -6,14 +6,37 @@ static NSString *const DeploymentSucceeded = @"DeploymentSucceeded"; static NSString *const LabelKey = @"label"; static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REPORT"; -@implementation CodePushStatusReport +@implementation CodePushTelemetryManager -+ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier ++ (NSDictionary *)getBinaryUpdateReport:(NSString *)appVersion { - return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; + NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; + if (previousStatusReportIdentifier == nil) { + [self recordDeploymentStatusReported:appVersion]; + return @{ @"appVersion": appVersion }; + } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { + [self recordDeploymentStatusReported:appVersion]; + if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { + NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; + NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; + return @{ + @"appVersion": appVersion, + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel + }; + } else { + // Previous status report was with a binary app version. + return @{ + @"appVersion": appVersion, + @"previousLabelOrAppVersion": previousStatusReportIdentifier + }; + } + } + + return nil; } -+ (NSDictionary *)getFailedUpdateStatusReport:(NSDictionary *)lastFailedPackage ++ (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage { return @{ @"package": lastFailedPackage, @@ -21,7 +44,7 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP }; } -+ (NSDictionary *)getNewPackageStatusReport:(NSDictionary *)currentPackage ++ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage { NSString *currentPackageIdentifier = [self getPackageStatusReportIdentifier:currentPackage]; NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; @@ -57,32 +80,9 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP return nil; } -+ (NSDictionary *)getNewAppVersionStatusReport:(NSString *)appVersion ++ (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier { - NSString *previousStatusReportIdentifier = [self getPreviousStatusReportIdentifier]; - if (previousStatusReportIdentifier == nil) { - [self recordDeploymentStatusReported:appVersion]; - return @{ @"appVersion": appVersion }; - } else if (![previousStatusReportIdentifier isEqualToString:appVersion]) { - [self recordDeploymentStatusReported:appVersion]; - if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { - NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; - NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; - return @{ - @"appVersion": appVersion, - @"previousDeploymentKey": previousDeploymentKey, - @"previousLabelOrAppVersion": previousLabel - }; - } else { - // Previous status report was with a binary app version. - return @{ - @"appVersion": appVersion, - @"previousLabelOrAppVersion": previousStatusReportIdentifier - }; - } - } - - return nil; + return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; } + (NSString *)getPackageStatusReportIdentifier:(NSDictionary *)package diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index 426b3c5..59758df 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -65,7 +65,7 @@ public class CodePush { // Helper classes. private CodePushPackage codePushPackage; private CodePushReactPackage codePushReactPackage; - private CodePushStatusReport codePushStatusReport; + private CodePushTelemetryManager codePushTelemetryManager; private CodePushNativeModule codePushNativeModule; // Config properties. @@ -86,7 +86,7 @@ public class CodePush { SoLoader.init(mainActivity, false); this.applicationContext = mainActivity.getApplicationContext(); this.codePushPackage = new CodePushPackage(mainActivity.getFilesDir().getAbsolutePath()); - this.codePushStatusReport = new CodePushStatusReport(this.applicationContext, CODE_PUSH_PREFERENCES); + this.codePushTelemetryManager = new CodePushTelemetryManager(this.applicationContext, CODE_PUSH_PREFERENCES); this.deploymentKey = deploymentKey; this.isDebugMode = isDebugMode; this.mainActivity = mainActivity; @@ -433,7 +433,7 @@ public class CodePush { try { JSONObject lastFailedPackageJSON = failedUpdates.getJSONObject(failedUpdates.length() - 1); WritableMap lastFailedPackage = CodePushUtils.convertJsonObjectToWriteable(lastFailedPackageJSON); - WritableMap failedStatusReport = codePushStatusReport.getFailedUpdateStatusReport(lastFailedPackage); + WritableMap failedStatusReport = codePushTelemetryManager.getRollbackReport(lastFailedPackage); if (failedStatusReport != null) { promise.resolve(failedStatusReport); return; @@ -445,14 +445,14 @@ public class CodePush { } else if (didUpdate) { WritableMap currentPackage = codePushPackage.getCurrentPackage(); if (currentPackage != null) { - WritableMap newPackageStatusReport = codePushStatusReport.getNewPackageStatusReport(currentPackage); + WritableMap newPackageStatusReport = codePushTelemetryManager.getUpdateReport(currentPackage); if (newPackageStatusReport != null) { promise.resolve(newPackageStatusReport); return; } } } else if (isRunningBinaryVersion) { - WritableMap newAppVersionStatusReport = codePushStatusReport.getNewAppVersionStatusReport(appVersion); + WritableMap newAppVersionStatusReport = codePushTelemetryManager.getBinaryUpdateReport(appVersion); if (newAppVersionStatusReport != null) { promise.resolve(newAppVersionStatusReport); return; diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java similarity index 87% rename from android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java rename to android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java index d3ffc76..86ae472 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePushStatusReport.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePushTelemetryManager.java @@ -6,7 +6,7 @@ import android.content.SharedPreferences; import com.facebook.react.bridge.WritableMap; import com.facebook.react.bridge.WritableNativeMap; -public class CodePushStatusReport { +public class CodePushTelemetryManager { private Context applicationContext; private final String CODE_PUSH_PREFERENCES; @@ -16,28 +16,46 @@ public class CodePushStatusReport { private final String LABEL_KEY = "label"; private final String LAST_DEPLOYMENT_REPORT_KEY = "CODE_PUSH_LAST_DEPLOYMENT_REPORT"; - public CodePushStatusReport(Context applicationContext, String codePushPreferencesKey) { + public CodePushTelemetryManager(Context applicationContext, String codePushPreferencesKey) { this.applicationContext = applicationContext; this.CODE_PUSH_PREFERENCES = codePushPreferencesKey; } - public String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) { - String[] parsedIdentifier = statusReportIdentifier.split(":"); - if (parsedIdentifier.length > 0) { - return parsedIdentifier[0]; - } else { - return null; + public WritableMap getBinaryUpdateReport(String appVersion) { + String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier(); + if (previousStatusReportIdentifier == null) { + this.recordDeploymentStatusReported(appVersion); + WritableNativeMap reportMap = new WritableNativeMap(); + reportMap.putString("appVersion", appVersion); + return reportMap; + } else if (!previousStatusReportIdentifier.equals(appVersion)) { + this.recordDeploymentStatusReported(appVersion); + WritableNativeMap reportMap = new WritableNativeMap(); + if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { + String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); + String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); + reportMap.putString("appVersion", appVersion); + reportMap.putString("previousDeploymentKey", previousDeploymentKey); + reportMap.putString("previousLabelOrAppVersion", previousLabel); + } else { + // Previous status report was with a binary app version. + reportMap.putString("appVersion", appVersion); + reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); + } + return reportMap; } + + return null; } - public WritableMap getFailedUpdateStatusReport(WritableMap lastFailedPackage) { + public WritableMap getRollbackReport(WritableMap lastFailedPackage) { WritableNativeMap reportMap = new WritableNativeMap(); reportMap.putMap("package", lastFailedPackage); reportMap.putString("status", DEPLOYMENT_FAILED_STATUS); return reportMap; } - public WritableMap getNewPackageStatusReport(WritableMap currentPackage) { + public WritableMap getUpdateReport(WritableMap currentPackage) { String currentPackageIdentifier = this.getPackageStatusReportIdentifier(currentPackage); String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier(); if (currentPackageIdentifier != null) { @@ -72,34 +90,16 @@ public class CodePushStatusReport { return null; } - public WritableMap getNewAppVersionStatusReport(String appVersion) { - String previousStatusReportIdentifier = this.getPreviousStatusReportIdentifier(); - if (previousStatusReportIdentifier == null) { - this.recordDeploymentStatusReported(appVersion); - WritableNativeMap reportMap = new WritableNativeMap(); - reportMap.putString("appVersion", appVersion); - return reportMap; - } else if (!previousStatusReportIdentifier.equals(appVersion)) { - this.recordDeploymentStatusReported(appVersion); - WritableNativeMap reportMap = new WritableNativeMap(); - if (this.isStatusReportIdentifierCodePushLabel(previousStatusReportIdentifier)) { - String previousDeploymentKey = this.getDeploymentKeyFromStatusReportIdentifier(previousStatusReportIdentifier); - String previousLabel = this.getVersionLabelFromStatusReportIdentifier(previousStatusReportIdentifier); - reportMap.putString("appVersion", appVersion); - reportMap.putString("previousDeploymentKey", previousDeploymentKey); - reportMap.putString("previousLabelOrAppVersion", previousLabel); - } else { - // Previous status report was with a binary app version. - reportMap.putString("appVersion", appVersion); - reportMap.putString("previousLabelOrAppVersion", previousStatusReportIdentifier); - } - return reportMap; + private String getDeploymentKeyFromStatusReportIdentifier(String statusReportIdentifier) { + String[] parsedIdentifier = statusReportIdentifier.split(":"); + if (parsedIdentifier.length > 0) { + return parsedIdentifier[0]; + } else { + return null; } - - return null; } - public String getPackageStatusReportIdentifier(WritableMap updatePackage) { + private String getPackageStatusReportIdentifier(WritableMap updatePackage) { // Because deploymentKeys can be dynamically switched, we use a // combination of the deploymentKey and label as the packageIdentifier. String deploymentKey = CodePushUtils.tryGetString(updatePackage, DEPLOYMENT_KEY_KEY); @@ -111,12 +111,12 @@ public class CodePushStatusReport { } } - public String getPreviousStatusReportIdentifier() { + private String getPreviousStatusReportIdentifier() { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); return settings.getString(LAST_DEPLOYMENT_REPORT_KEY, null); } - public String getVersionLabelFromStatusReportIdentifier(String statusReportIdentifier) { + private String getVersionLabelFromStatusReportIdentifier(String statusReportIdentifier) { String[] parsedIdentifier = statusReportIdentifier.split(":"); if (parsedIdentifier.length > 1) { return parsedIdentifier[1]; @@ -125,11 +125,11 @@ public class CodePushStatusReport { } } - public boolean isStatusReportIdentifierCodePushLabel(String statusReportIdentifier) { + private boolean isStatusReportIdentifierCodePushLabel(String statusReportIdentifier) { return statusReportIdentifier != null && statusReportIdentifier.contains(":"); } - public void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) { + private void recordDeploymentStatusReported(String appVersionOrPackageIdentifier) { SharedPreferences settings = applicationContext.getSharedPreferences(CODE_PUSH_PREFERENCES, 0); settings.edit().putString(LAST_DEPLOYMENT_REPORT_KEY, appVersionOrPackageIdentifier).commit(); } diff --git a/request-fetch-adapter.js b/request-fetch-adapter.js index 4aef90e..cc22b53 100644 --- a/request-fetch-adapter.js +++ b/request-fetch-adapter.js @@ -32,7 +32,7 @@ module.exports = { }; function getSDKVersion() { - return require("./package.json").dependencies["code-push"]; + return require("./package.json").dependencies["code-push"]; } function getHttpMethodName(verb) { From 3e5d7fd7c9b2f32d40782959067963696c207f67 Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Wed, 27 Jan 2016 18:32:21 -0800 Subject: [PATCH 7/8] whitespace --- request-fetch-adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/request-fetch-adapter.js b/request-fetch-adapter.js index cc22b53..eb61622 100644 --- a/request-fetch-adapter.js +++ b/request-fetch-adapter.js @@ -4,7 +4,7 @@ module.exports = { callback = requestBody; requestBody = null; } - + const headers = { "Accept": "application/json", "Content-Type": "application/json", From 509cc0fbac67b7171a08a803333e37871ea9ed0e Mon Sep 17 00:00:00 2001 From: Geoffrey Goh Date: Thu, 28 Jan 2016 03:56:20 -0800 Subject: [PATCH 8/8] feedback --- CodePush.h | 2 +- CodePush.m | 47 ++++++++++--------- CodePushTelemetryManager.m | 40 ++++++++-------- .../microsoft/codepush/react/CodePush.java | 2 +- 4 files changed, 48 insertions(+), 43 deletions(-) diff --git a/CodePush.h b/CodePush.h index 7704421..e3a016d 100644 --- a/CodePush.h +++ b/CodePush.h @@ -91,8 +91,8 @@ failCallback:(void (^)(NSError *err))failCallback; @interface CodePushTelemetryManager : NSObject + (NSDictionary *)getBinaryUpdateReport:(NSString *)appVersion; -+ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage; + (NSDictionary *)getRollbackReport:(NSDictionary *)lastFailedPackage; ++ (NSDictionary *)getUpdateReport:(NSDictionary *)currentPackage; @end diff --git a/CodePush.m b/CodePush.m index 933621d..5e2370e 100644 --- a/CodePush.m +++ b/CodePush.m @@ -503,32 +503,35 @@ RCT_EXPORT_METHOD(notifyApplicationReady:(RCTPromiseResolveBlock)resolve RCT_EXPORT_METHOD(getNewStatusReport:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { - if (needToReportRollback) { - needToReportRollback = NO; - NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; - NSMutableArray *failedUpdates = [preferences objectForKey:FailedUpdatesKey]; - if (failedUpdates) { - NSDictionary *lastFailedPackage = [failedUpdates lastObject]; - if (lastFailedPackage) { - resolve([CodePushTelemetryManager getRollbackReport:lastFailedPackage]); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + if (needToReportRollback) { + needToReportRollback = NO; + NSUserDefaults *preferences = [NSUserDefaults standardUserDefaults]; + NSMutableArray *failedUpdates = [preferences objectForKey:FailedUpdatesKey]; + if (failedUpdates) { + NSDictionary *lastFailedPackage = [failedUpdates lastObject]; + if (lastFailedPackage) { + resolve([CodePushTelemetryManager getRollbackReport:lastFailedPackage]); + return; + } + } + } else if (_isFirstRunAfterUpdate) { + NSError *error; + NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; + if (!error && currentPackage) { + resolve([CodePushTelemetryManager getUpdateReport:currentPackage]); return; } - } - } else if (_isFirstRunAfterUpdate) { - NSError *error; - NSDictionary *currentPackage = [CodePushPackage getCurrentPackage:&error]; - if (!error && currentPackage) { - resolve([CodePushTelemetryManager getUpdateReport:currentPackage]); + } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { + // Check if the current appVersion has been reported. + NSString *appVersion = [[CodePushConfig current] appVersion]; + resolve([CodePushTelemetryManager getBinaryUpdateReport:appVersion]); return; } - } else if (isRunningBinaryVersion || [_bridge.bundleURL.scheme hasPrefix:@"http"]) { - // Check if the current appVersion has been reported. - NSString *appVersion = [[CodePushConfig current] appVersion]; - resolve([CodePushTelemetryManager getBinaryUpdateReport:appVersion]); - return; - } - - resolve(nil); + + resolve(nil); + }); } /* diff --git a/CodePushTelemetryManager.m b/CodePushTelemetryManager.m index 6c5194e..1feff55 100644 --- a/CodePushTelemetryManager.m +++ b/CodePushTelemetryManager.m @@ -20,16 +20,16 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; return @{ - @"appVersion": appVersion, - @"previousDeploymentKey": previousDeploymentKey, - @"previousLabelOrAppVersion": previousLabel - }; + @"appVersion": appVersion, + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel + }; } else { // Previous status report was with a binary app version. return @{ - @"appVersion": appVersion, - @"previousLabelOrAppVersion": previousStatusReportIdentifier - }; + @"appVersion": appVersion, + @"previousLabelOrAppVersion": previousStatusReportIdentifier + }; } } @@ -52,27 +52,27 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP if (previousStatusReportIdentifier == nil) { [self recordDeploymentStatusReported:currentPackageIdentifier]; return @{ - @"package": currentPackage, - @"status": DeploymentSucceeded - }; + @"package": currentPackage, + @"status": DeploymentSucceeded + }; } else if (![previousStatusReportIdentifier isEqualToString:currentPackageIdentifier]) { [self recordDeploymentStatusReported:currentPackageIdentifier]; if ([self isStatusReportIdentifierCodePushLabel:previousStatusReportIdentifier]) { NSString *previousDeploymentKey = [self getDeploymentKeyFromStatusReportIdentifier:previousStatusReportIdentifier]; NSString *previousLabel = [self getVersionLabelFromStatusReportIdentifier:previousStatusReportIdentifier]; return @{ - @"package": currentPackage, - @"status": DeploymentSucceeded, - @"previousDeploymentKey": previousDeploymentKey, - @"previousLabelOrAppVersion": previousLabel - }; + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"previousDeploymentKey": previousDeploymentKey, + @"previousLabelOrAppVersion": previousLabel + }; } else { // Previous status report was with a binary app version. return @{ - @"package": currentPackage, - @"status": DeploymentSucceeded, - @"previousLabelOrAppVersion": previousStatusReportIdentifier - }; + @"package": currentPackage, + @"status": DeploymentSucceeded, + @"previousLabelOrAppVersion": previousStatusReportIdentifier + }; } } } @@ -80,6 +80,8 @@ static NSString *const LastDeploymentReportKey = @"CODE_PUSH_LAST_DEPLOYMENT_REP return nil; } +#pragma mark - private methods + + (NSString *)getDeploymentKeyFromStatusReportIdentifier:(NSString *)statusReportIdentifier { return [[statusReportIdentifier componentsSeparatedByString:@":"] firstObject]; diff --git a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java index 59758df..937806f 100644 --- a/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java +++ b/android/app/src/main/java/com/microsoft/codepush/react/CodePush.java @@ -63,10 +63,10 @@ public class CodePush { private final String REACT_DEV_BUNDLE_CACHE_FILE_NAME = "ReactNativeDevBundle.js"; // Helper classes. + private CodePushNativeModule codePushNativeModule; private CodePushPackage codePushPackage; private CodePushReactPackage codePushReactPackage; private CodePushTelemetryManager codePushTelemetryManager; - private CodePushNativeModule codePushNativeModule; // Config properties. private String deploymentKey;