Skip to content
This repository has been archived by the owner on Oct 1, 2018. It is now read-only.

Commit

Permalink
Merge pull request #2 from nordnet/master
Browse files Browse the repository at this point in the history
merge from head
  • Loading branch information
Mikey1982 authored Aug 30, 2016
2 parents 56633c5 + 76225fd commit 9f28822
Show file tree
Hide file tree
Showing 14 changed files with 129 additions and 29 deletions.
15 changes: 14 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
# Change Log

## 1.5.0 (2016-08-30)

**Bug fixes:**

- [Issue #197](https://github.com/nordnet/cordova-hot-code-push/issues/197). Android can now update files with spaces in their names.

**Improvements:**

- Merged [pull request #204](https://github.com/nordnet/cordova-hot-code-push/pull/204). Initial installation of the assets on the external storage on Android is now much faster. Thanks to [@Mikey1982](https://github.com/Mikey1982).
- Added new JS method: `getVersionInfo`. Based on [pull request #170](https://github.com/nordnet/cordova-hot-code-push/pull/170) from [@Manduro](https://github.com/Manduro) - thank you. For documentation, please, refer to [wikki page](https://github.com/nordnet/cordova-hot-code-push/wiki/Get-version-information).

## 1.4.0 (2016-06-21)

**Bug fixes:**
- [Issue #155](https://github.com/nordnet/cordova-hot-code-push/issues/155). Android app should not crash if server has a bad chcp.json file.

- [Issue #155](https://github.com/nordnet/cordova-hot-code-push/issues/155). Android app should not crash if server has a bad `chcp.json` file.

**Improvements:**

- [Issue #153](https://github.com/nordnet/cordova-hot-code-push/issues/153). You can now pass `chcp.json` file url into `fetchUpdate` method on JS side. Also, you can provide additional HTTP headers to the request. For example, authorization info. These headers will be used for loading configuration files and updated/changed files from your server. Thanks to [@davidovich](https://github.com/davidovich) for [pull request #150](https://github.com/nordnet/cordova-hot-code-push/pull/150).
- [Issue #99](https://github.com/nordnet/cordova-hot-code-push/issues/99). iOS build version can now be a string. So, changing it from 1.0.0 to 1.0.1 will trigger reinstallation of `www` folder. Before that it had to be an integer.
- [Issue #160](https://github.com/nordnet/cordova-hot-code-push/issues/160). Old releases are now gets removed after update installation. Previously cleanup was performed only on application restart.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ As a result, your application receives updates of the web content as soon as pos

### Installation

This requires cordova 5.0+ (current stable 1.4.0)
This requires cordova 5.0+ (current stable 1.5.0)

```sh
cordova plugin add cordova-hot-code-push-plugin
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "cordova-hot-code-push-plugin",
"version": "1.4.0",
"version": "1.5.0",
"description": "Cordova plugin to perform code updates on the fly",
"cordova": {
"id": "cordova-hot-code-push-plugin",
Expand Down Expand Up @@ -35,7 +35,7 @@
}
],
"dependencies": {
"xml2js": ">=0.4"
"xml2js": "^0.4"
},
"author": "Nikolay Demyankov for Nordnet Bank AB",
"license": "MIT",
Expand Down
2 changes: 1 addition & 1 deletion plugin.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>

<plugin id="cordova-hot-code-push-plugin" version="1.4.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<plugin id="cordova-hot-code-push-plugin" version="1.5.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">

<name>Hot Code Push Plugin</name>
<description>Cordova plugin to perform code updates on the fly</description>
Expand Down
21 changes: 21 additions & 0 deletions src/android/src/com/nordnetab/chcp/main/HotCodePushPlugin.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.nordnetab.chcp.main;

import android.content.Context;
import android.os.Handler;
import android.text.TextUtils;
import android.util.Log;
Expand Down Expand Up @@ -251,6 +252,8 @@ public boolean execute(String action, CordovaArgs args, CallbackContext callback
jsRequestAppUpdate(args, callbackContext);
} else if (JSAction.IS_UPDATE_AVAILABLE_FOR_INSTALLATION.equals(action)) {
jsIsUpdateAvailableForInstallation(callbackContext);
} else if (JSAction.GET_VERSION_INFO.equals(action)) {
jsGetVersionInfo(callbackContext);
} else {
cmdProcessed = false;
}
Expand Down Expand Up @@ -444,6 +447,24 @@ private void jsIsUpdateAvailableForInstallation(final CallbackContext callback)
callback.sendPluginResult(pluginResult);
}

/**
* Get information about app and web versions.
*
* @param callback callback where to send the result
*/
private void jsGetVersionInfo(final CallbackContext callback) {
final Context context = cordova.getActivity();
final Map<String, Object> data = new HashMap<String, Object>();
data.put("currentWebVersion", pluginInternalPrefs.getCurrentReleaseVersionName());
data.put("readyToInstallWebVersion", pluginInternalPrefs.getReadyForInstallationReleaseVersionName());
data.put("previousWebVersion", pluginInternalPrefs.getPreviousReleaseVersionName());
data.put("appVersion", VersionHelper.applicationVersionName(context));
data.put("buildVersion", VersionHelper.applicationVersionCode(context));

final PluginResult pluginResult = PluginResultHelper.createPluginResult(null, data, null);
callback.sendPluginResult(pluginResult);
}

// convenience method
private void fetchUpdate() {
fetchUpdate(null, new FetchUpdateOptions());
Expand Down
1 change: 1 addition & 0 deletions src/android/src/com/nordnetab/chcp/main/js/JSAction.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public final class JSAction {
public static final String CONFIGURE = "jsConfigure";
public static final String REQUEST_APP_UPDATE = "jsRequestAppUpdate";
public static final String IS_UPDATE_AVAILABLE_FOR_INSTALLATION = "jsIsUpdateAvailableForInstallation";
public static final String GET_VERSION_INFO = "jsGetVersionInfo";

// Private API
public static final String INIT = "jsInitPlugin";
Expand Down
36 changes: 18 additions & 18 deletions src/android/src/com/nordnetab/chcp/main/utils/AssetsHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.nordnetab.chcp.main.events.AssetsInstalledEvent;
import com.nordnetab.chcp.main.events.BeforeAssetsInstalledEvent;

import org.apache.cordova.LOG;
import org.greenrobot.eventbus.EventBus;

import java.io.File;
Expand Down Expand Up @@ -54,11 +53,8 @@ public static void copyAssetDirectoryToAppDirectory(final Context applicationCon
@Override
public void run() {
try {
long start = System.currentTimeMillis();
copyAssetDirectory(applicationContext, fromDirectory, toDirectory);
execute(applicationContext, fromDirectory, toDirectory);
EventBus.getDefault().post(new AssetsInstalledEvent());
long time = System.currentTimeMillis() - start;
LOG.d("CHCP", "Copied assets in : %d ms", time);
} catch (IOException e) {
e.printStackTrace();
EventBus.getDefault().post(new AssetsInstallationErrorEvent());
Expand All @@ -69,31 +65,35 @@ public void run() {
}).start();
}

private static void copyAssetDirectory(Context applicationContext, String fromDirectory, String toDirectory) throws IOException {
private static void execute(Context applicationContext, String fromDirectory, String toDirectory) throws IOException {
// recreate cache folder
FilesUtility.delete(toDirectory);
FilesUtility.ensureDirectoryExists(toDirectory);
JarFile jarFile = new JarFile(applicationContext.getApplicationInfo().sourceDir);

String prefix = "assets/" + fromDirectory;
int prefixLength = prefix.length();
Enumeration<JarEntry> enu = jarFile.entries();
while (enu.hasMoreElements()) {
JarEntry fileJarEntry = enu.nextElement();
String name = fileJarEntry.getName();
if (!fileJarEntry.isDirectory() && name.startsWith(prefix)) {

final String assetsDir = "assets/" + fromDirectory;
copyAssets(applicationContext.getApplicationInfo().sourceDir, assetsDir, toDirectory);
}

private static void copyAssets(final String appJarPath, final String assetsDir, final String toDirectory) throws IOException {
final JarFile jarFile = new JarFile(appJarPath);
final int prefixLength = assetsDir.length();
final Enumeration<JarEntry> filesEnumeration = jarFile.entries();

while (filesEnumeration.hasMoreElements()) {
final JarEntry fileJarEntry = filesEnumeration.nextElement();
final String name = fileJarEntry.getName();
if (!fileJarEntry.isDirectory() && name.startsWith(assetsDir)) {
final String destinationFileAbsolutePath = Paths.get(toDirectory, name.substring(prefixLength));

copyAssetFile(jarFile.getInputStream(fileJarEntry), destinationFileAbsolutePath);
copyFile(jarFile.getInputStream(fileJarEntry), destinationFileAbsolutePath);
}
}

}

/**
* Copies asset file to destination path
*/
private static void copyAssetFile(InputStream in, String destinationFilePath) throws IOException {
private static void copyFile(final InputStream in, final String destinationFilePath) throws IOException {
FilesUtility.ensureDirectoryExists(new File(destinationFilePath).getParent());
OutputStream out = new FileOutputStream(destinationFilePath);
// Transfer bytes from in to out
Expand Down
9 changes: 7 additions & 2 deletions src/android/src/com/nordnetab/chcp/main/utils/URLUtility.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package com.nordnetab.chcp.main.utils;

import android.util.Log;

import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.net.URLDecoder;

Expand All @@ -21,12 +24,14 @@ public class URLUtility {
public static URL stringToUrl(String urlString) {
URL url = null;
try {
url = new URL(URLDecoder.decode(urlString, "UTF-8"));
url = new URL(urlString);
final URI uri = new URI(url.getProtocol(), url.getUserInfo(), url.getHost(), url.getPort(), url.getPath(), url.getQuery(), url.getRef());
url = uri.toURL();
} catch (Exception e) {
try {
url = new URL(urlString);
} catch (MalformedURLException e2) {
e2.printStackTrace();
Log.d("CHCP", "Failed to transfer url string \"" + urlString + "\" to actual url", e2);
}
}

Expand Down
22 changes: 20 additions & 2 deletions src/android/src/com/nordnetab/chcp/main/utils/VersionHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import android.content.Context;
import android.content.pm.PackageManager;
import android.util.Log;

/**
* Created by Nikolay Demyankov on 30.07.15.
Expand All @@ -19,14 +20,31 @@ private VersionHelper() {
* @param context application context
* @return build version
*/
public static int applicationVersionCode(Context context) {
public static int applicationVersionCode(final Context context) {
int versionCode = 0;
try {
versionCode = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionCode;
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
Log.d("CHCP", "Can't get version code", e);
}

return versionCode;
}

/**
* Getter for application version name.
*
* @param context application context
* @return version name
*/
public static String applicationVersionName(final Context context) {
String versionName = "";
try {
versionName = context.getPackageManager().getPackageInfo(context.getPackageName(), 0).versionName;
} catch (PackageManager.NameNotFoundException e) {
Log.d("CHCP", "Can't get version name", e);
}

return versionName;
}
}
7 changes: 7 additions & 0 deletions src/ios/HCPPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,4 +66,11 @@
*/
- (void)jsIsUpdateAvailableForInstallation:(CDVInvokedUrlCommand *)command;

/**
* Get information about app and web versions.
*
* @param command command with which the method is called
*/
- (void)jsGetVersionInfo:(CDVInvokedUrlCommand *)command;

@end
11 changes: 11 additions & 0 deletions src/ios/HCPPlugin.m
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,17 @@ - (void)jsIsUpdateAvailableForInstallation:(CDVInvokedUrlCommand *)command {
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}

- (void)jsGetVersionInfo:(CDVInvokedUrlCommand *)command {
NSDictionary *data = @{@"currentWebVersion": _pluginInternalPrefs.currentReleaseVersionName,
@"readyToInstallWebVersion": _pluginInternalPrefs.readyForInstallationReleaseVersionName,
@"previousWebVersion": _pluginInternalPrefs.previousReleaseVersionName,
@"appVersion": [NSBundle applicationVersionName],
@"buildVersion": [NSBundle applicationBuildVersion]};

CDVPluginResult *result = [CDVPluginResult pluginResultWithActionName:nil data:data error:nil];
[self.commandDelegate sendPluginResult:result callbackId:command.callbackId];
}

- (void)sendPluginNotReadyToWorkMessageForEvent:(NSString *)eventName callbackID:(NSString *)callbackID {
NSError *error = [NSError errorWithCode:kHCPAssetsNotYetInstalledErrorCode
description:@"WWW folder from the bundle is not yet installed on the external device. Please, wait for this operation to finish."];
Expand Down
7 changes: 7 additions & 0 deletions src/ios/Utils/NSBundle+HCPExtension.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@
*/
+ (NSString *)applicationBuildVersion;

/**
* Getter for application's version name.
*
* @return version name of the app
*/
+ (NSString *)applicationVersionName;

/**
* Path to the www folder in the application bundle.
*
Expand Down
8 changes: 7 additions & 1 deletion src/ios/Utils/NSBundle+HCPExtension.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,13 @@ @implementation NSBundle (HCPExtension)
+ (NSString *)applicationBuildVersion {
NSBundle *mainBundle = [NSBundle mainBundle];

return [mainBundle objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey];
return [mainBundle objectForInfoDictionaryKey:@"CFBundleVersion"];
}

+ (NSString *)applicationVersionName {
NSBundle *mainBundle = [NSBundle mainBundle];

return [mainBundle objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
}

+ (NSString *)pathToWwwFolder {
Expand Down
13 changes: 12 additions & 1 deletion www/chcp.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ var exec = require('cordova/exec'),
INSTALL_UPDATE: 'jsInstallUpdate',
CONFIGURE: 'jsConfigure',
REQUEST_APP_UPDATE: 'jsRequestAppUpdate',
IS_UPDATE_AVAILABLE_FOR_INSTALLATION: 'jsIsUpdateAvailableForInstallation'
IS_UPDATE_AVAILABLE_FOR_INSTALLATION: 'jsIsUpdateAvailableForInstallation',
GET_INFO: 'jsGetVersionInfo'
};

// Called when Cordova is ready for work.
Expand Down Expand Up @@ -262,6 +263,16 @@ var chcp = {
*/
isUpdateAvailableForInstallation: function(callback) {
callNativeMethod(pluginNativeMethod.IS_UPDATE_AVAILABLE_FOR_INSTALLATION, null, callback);
},

/**
* Get information about the current version like current release version, app build version and so on.
* The "data" property of the callback will contain all the information.
*
* @param {Callback(error, data)} callback - called, when information is retrieved from the native side.
*/
getVersionInfo: function(callback) {
callNativeMethod(pluginNativeMethod.GET_INFO, null, callback);
}
};

Expand Down

0 comments on commit 9f28822

Please sign in to comment.