This commit is contained in:
Geoffrey Goh
2015-11-24 17:28:30 -08:00
parent a636482846
commit c5ec81101a
16 changed files with 68 additions and 167 deletions

View File

@@ -2,7 +2,9 @@
var requestFetchAdapter = require("./request-fetch-adapter.js");
var Sdk = require("code-push/script/acquisition-sdk").AcquisitionManager;
var { NativeCodePush, PackageMixins, Alert } = require("./CodePushNativePlatformAdapter");
var NativeCodePush = require("react-native").NativeModules.CodePush;
var PackageMixins = require("./package-mixins")(NativeCodePush);
var { Alert } = require("./CodePushNativePlatformAdapter");
function checkForUpdate(deploymentKey = null) {
var config, sdk;

View File

@@ -1,38 +1,9 @@
'use strict';
var NativeCodePush = require("react-native").NativeModules.CodePush;
var Platform = require("Platform");
var Alert;
if (Platform.OS === "android") {
/*
* Promisify native methods. Assumes that every native method takes
* two callback functions, resolve and reject.
*/
var methodsToPromisify = [
"installUpdate",
"downloadUpdate",
"getConfiguration",
"getCurrentPackage",
"isFailedUpdate",
"isFirstRun",
"notifyApplicationReady",
"setDeploymentKey"
];
methodsToPromisify.forEach((methodName) => {
var aMethod = NativeCodePush[methodName];
NativeCodePush[methodName] = function() {
var args = [].slice.apply(arguments);
return new Promise((resolve, reject) => {
args.push(resolve);
args.push(reject);
aMethod.apply(this, args);
});
}
});
var CodePushDialog = require("react-native").NativeModules.CodePushDialog;
Alert = {
alert: function(title, message, buttons) {
@@ -58,10 +29,6 @@ if (Platform.OS === "android") {
Alert = AlertIOS;
}
var PackageMixins = require("./package-mixins")(NativeCodePush);
module.exports = {
NativeCodePush: NativeCodePush,
PackageMixins: PackageMixins,
Alert: Alert
}

View File

@@ -10,7 +10,7 @@ import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.microsoft.reactnativecodepush.CodePush;
import com.microsoft.codepush.react.CodePush;
public class MainActivity extends FragmentActivity implements DefaultHardwareBackBtnHandler {
@@ -25,7 +25,7 @@ public class MainActivity extends FragmentActivity implements DefaultHardwareBac
super.onCreate(savedInstanceState);
mReactRootView = new ReactRootView(this);
codePush = new CodePush("DEPLOYMENT_KEY_HERE", this);
codePush = new CodePush("d73bf5d8-4fbd-4e55-a837-accd328a21ba", this);
ReactInstanceManager.Builder builder = ReactInstanceManager.builder()
.setApplication(getApplication())

View File

@@ -112,7 +112,7 @@ After installing the plugin and sync-ing your Android Studio project with Gradle
```java
...
// 1. Import the plugin class
import com.microsoft.reactnativecodepush.CodePush;
import com.microsoft.codepush.react.CodePush;
// 2. Optional: extend FragmentActivity if you intend to show a dialog prompting users about updates.
public class MainActivity extends FragmentActivity implements DefaultHardwareBackBtnHandler {
@@ -122,7 +122,6 @@ After installing the plugin and sync-ing your Android Studio project with Gradle
protected void onCreate(Bundle savedInstanceState) {
...
// 3. Initialize CodePush with your deployment key and an instance of your MainActivity.
// You can also set the deployment key in code by assigning the key to the `[CodePushConfig current].deploymentKey` property.*
CodePush codePush = new CodePush("d73bf5d8-4fbd-4e55-a837-accd328a21ba", this);
...
mReactInstanceManager = ReactInstanceManager.builder()

View File

@@ -1,5 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.microsoft.reactnativecodepush">
package="com.microsoft.codepush.react">
<uses-permission android:name="android.permission.INTERNET" />

View File

@@ -1,13 +1,13 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.LifecycleEventListener;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;
@@ -19,6 +19,8 @@ import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import org.json.JSONException;
import org.json.JSONObject;
@@ -35,8 +37,6 @@ import java.util.TimerTask;
public class CodePush {
private String deploymentKey;
private boolean resumablePendingUpdateAvailable = false;
private boolean didUpdate = false;
private Timer timer;
@@ -55,7 +55,12 @@ public class CodePush {
private CodePushPackage codePushPackage;
private CodePushReactPackage codePushReactPackage;
private CodePushNativeModule codePushNativeModule;
private CodePushConfig codePushConfig;
// Config properties.
private String deploymentKey;
private String appVersion;
private int buildVersion;
private final String serverUrl = "https://codepush.azurewebsites.net/";
private Activity mainActivity;
private Context applicationContext;
@@ -66,7 +71,17 @@ public class CodePush {
this.codePushPackage = new CodePushPackage(mainActivity.getFilesDir().getAbsolutePath());
this.mainActivity = mainActivity;
this.applicationContext = mainActivity.getApplicationContext();
this.codePushConfig = new CodePushConfig(deploymentKey, this.applicationContext);
this.deploymentKey = deploymentKey;
PackageInfo pInfo = null;
try {
pInfo = applicationContext.getPackageManager().getPackageInfo(applicationContext.getPackageName(), 0);
appVersion = pInfo.versionName;
buildVersion = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new CodePushUnknownException("Unable to get package info for " + applicationContext.getPackageName(), e);
}
checkForPendingUpdate(/*needsRestart*/ false);
}
@@ -113,12 +128,14 @@ public class CodePush {
JSONObject pendingUpdateJSON = new JSONObject(pendingUpdateString);
String pendingHash = pendingUpdateJSON.getString(PENDING_UPDATE_HASH_KEY);
String currentHash = codePushPackage.getCurrentPackageHash();
if (pendingHash.equals(currentHash)) {
int rollbackTimeout = pendingUpdateJSON.getInt(PENDING_UPDATE_ROLLBACK_TIMEOUT_KEY);
initializeUpdateWithRollbackTimeout(rollbackTimeout, needsRestart);
settings.edit().remove(PENDING_UPDATE_KEY).commit();
if (!pendingHash.equals(currentHash)) {
throw new CodePushUnknownException("Pending hash " + pendingHash +
" and current hash " + currentHash + " are different");
}
int rollbackTimeout = pendingUpdateJSON.getInt(PENDING_UPDATE_ROLLBACK_TIMEOUT_KEY);
initializeUpdateWithRollbackTimeout(rollbackTimeout, needsRestart);
settings.edit().remove(PENDING_UPDATE_KEY).commit();
} catch (JSONException e) {
// Should not happen.
throw new CodePushUnknownException("Unable to parse pending update metadata " +
@@ -136,16 +153,6 @@ public class CodePush {
}
}
private WritableMap constantsToExport() {
// Export the values of the CodePushInstallMode enum
// so that the script-side can easily stay in sync
WritableMap map = new WritableNativeMap();
map.putInt("codePushInstallModeImmediate", CodePushInstallMode.IMMEDIATE.getValue());
map.putInt("codePushInstallModeOnNextRestart", CodePushInstallMode.ON_NEXT_RESTART.getValue());
map.putInt("codePushInstallModeOnNextResume", CodePushInstallMode.ON_NEXT_RESUME.getValue());
return map;
}
private void initializeUpdateWithRollbackTimeout(int rollbackTimeout, boolean needsRestart) {
didUpdate = true;
@@ -248,15 +255,13 @@ public class CodePush {
private class CodePushNativeModule extends ReactContextBaseJavaModule {
private void loadBundle() {
String assetsBundleFileUrl = CodePush.this.getBundleUrl(CodePush.this.assetsBundleFileName);
Intent intent = mainActivity.getIntent();
mainActivity.finish();
mainActivity.startActivity(intent);
}
@ReactMethod
public void installUpdate(ReadableMap updatePackage, int rollbackTimeout, int installMode,
Callback resolve, Callback reject) {
public void installUpdate(ReadableMap updatePackage, int rollbackTimeout, int installMode, Promise promise) {
try {
codePushPackage.installPackage(updatePackage);
if (installMode != CodePushInstallMode.IMMEDIATE.getValue()) {
@@ -268,15 +273,15 @@ public class CodePush {
savePendingUpdate(pendingHash, rollbackTimeout);
}
}
resolve.invoke("");
promise.resolve("");
} catch (IOException e) {
e.printStackTrace();
reject.invoke(e.getMessage());
promise.reject(e.getMessage());
}
}
@ReactMethod
public void downloadUpdate(final ReadableMap updatePackage, final Callback resolve, final Callback reject) {
public void downloadUpdate(final ReadableMap updatePackage, final Promise promise) {
try {
codePushPackage.downloadPackage(applicationContext, updatePackage, new DownloadProgressCallback() {
@Override
@@ -288,51 +293,56 @@ public class CodePush {
});
WritableMap newPackage = codePushPackage.getPackage(CodePushUtils.tryGetString(updatePackage, codePushPackage.PACKAGE_HASH_KEY));
resolve.invoke(newPackage);
promise.resolve(newPackage);
} catch (IOException e) {
e.printStackTrace();
reject.invoke(e.getMessage());
promise.reject(e.getMessage());
}
}
@ReactMethod
public void getConfiguration(Callback resolve, Callback reject) {
resolve.invoke(codePushConfig.getConfiguration());
public void getConfiguration(Promise promise) {
WritableNativeMap configMap = new WritableNativeMap();
configMap.putString("appVersion", appVersion);
configMap.putInt("buildVersion", buildVersion);
configMap.putString("deploymentKey", deploymentKey);
configMap.putString("serverUrl", serverUrl);
promise.resolve(configMap);
}
@ReactMethod
public void getCurrentPackage(Callback resolve, Callback reject) {
public void getCurrentPackage(Promise promise) {
try {
resolve.invoke(codePushPackage.getCurrentPackage());
promise.resolve(codePushPackage.getCurrentPackage());
} catch (IOException e) {
e.printStackTrace();
reject.invoke(e.getMessage());
promise.reject(e.getMessage());
}
}
@ReactMethod
public void isFailedUpdate(String packageHash, Callback resolve, Callback reject) {
resolve.invoke(isFailedHash(packageHash));
public void isFailedUpdate(String packageHash, Promise promise) {
promise.resolve(isFailedHash(packageHash));
}
@ReactMethod
public void isFirstRun(String packageHash, Callback resolve, Callback reject) {
public void isFirstRun(String packageHash, Promise promise) {
try {
boolean isFirstRun = didUpdate
&& packageHash != null
&& packageHash.length() > 0
&& packageHash.equals(codePushPackage.getCurrentPackageHash());
resolve.invoke(isFirstRun);
promise.resolve(isFirstRun);
} catch (IOException e) {
e.printStackTrace();
reject.invoke(e.getMessage());
promise.reject(e.getMessage());
}
}
@ReactMethod
public void notifyApplicationReady(Callback resolve, Callback reject) {
public void notifyApplicationReady(Promise promise) {
cancelRollbackTimer();
resolve.invoke("");
promise.resolve("");
}
@ReactMethod

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import android.app.Activity;
import android.app.AlertDialog;

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
public enum CodePushInstallMode {
IMMEDIATE(0),

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import java.net.MalformedURLException;

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import android.content.Context;

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
public class CodePushUnknownException extends RuntimeException {

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.NoSuchKeyException;

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableNativeMap;

View File

@@ -1,4 +1,4 @@
package com.microsoft.reactnativecodepush;
package com.microsoft.codepush.react;
public interface DownloadProgressCallback {
void call(DownloadProgress downloadProgress);

View File

@@ -1,69 +0,0 @@
package com.microsoft.reactnativecodepush;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableNativeMap;
public class CodePushConfig {
private String appVersion;
private int buildVersion;
private String deploymentKey;
private String serverUrl = "https://codepush.azurewebsites.net/";
public CodePushConfig(String deploymentKey, Context applicationContext) {
this.deploymentKey = deploymentKey;
PackageInfo pInfo = null;
try {
pInfo = applicationContext.getPackageManager().getPackageInfo(applicationContext.getPackageName(), 0);
appVersion = pInfo.versionName;
buildVersion = pInfo.versionCode;
} catch (PackageManager.NameNotFoundException e) {
throw new CodePushUnknownException("Unable to get package info for " + applicationContext.getPackageName(), e);
}
}
public void setDeploymentKey(String deploymentKey) {
this.deploymentKey = deploymentKey;
}
public String getDeploymentKey() {
return deploymentKey;
}
public void setServerUrl(String serverUrl) {
this.serverUrl = serverUrl;
}
public String getServerUrl() {
return serverUrl;
}
public void setAppVersion(String appVersion) {
this.appVersion = appVersion;
}
public String getAppVersion() {
return appVersion;
}
public void setBuildVersion(int buildVersion) {
this.buildVersion = buildVersion;
}
public int getBuildVersion() {
return buildVersion;
}
public ReadableMap getConfiguration() {
WritableNativeMap configMap = new WritableNativeMap();
configMap.putString("appVersion", appVersion);
configMap.putInt("buildVersion", buildVersion);
configMap.putString("deploymentKey", deploymentKey);
configMap.putString("serverUrl", serverUrl);
return configMap;
}
}

View File

@@ -1,13 +1,5 @@
var Platform = require("Platform");
var EventEmitter;
if (Platform.OS === "android") {
var { DeviceEventEmitter } = require("react-native");
EventEmitter = DeviceEventEmitter;
} else if (Platform.OS === "ios") {
var { NativeAppEventEmitter } = require("react-native");
EventEmitter = NativeAppEventEmitter;
}
var { DeviceEventEmitter } = require("react-native");
module.exports = (NativeCodePush) => {
var remote = {
@@ -22,7 +14,7 @@ module.exports = (NativeCodePush) => {
var downloadProgressSubscription;
if (downloadProgressCallback) {
// Use event subscription to obtain download progress.
downloadProgressSubscription = EventEmitter.addListener(
downloadProgressSubscription = DeviceEventEmitter.addListener(
"CodePushDownloadProgress",
downloadProgressCallback
);