Skip to content

Commit

Permalink
Trying to fix hcp issues
Browse files Browse the repository at this point in the history
Added a retry for blacklisted version
Added a cordova hook to force the webapp to switch to a new AssetBundle before reloading the webview
  • Loading branch information
Mathieu Durand committed Feb 1, 2017
1 parent 10d4ddb commit ef7b999
Show file tree
Hide file tree
Showing 5 changed files with 158 additions and 21 deletions.
31 changes: 31 additions & 0 deletions src/android/AssetBundle.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.HashSet;
Expand Down Expand Up @@ -77,6 +78,9 @@ public AssetBundle(CordovaResourceApi resourceApi, Uri directoryUri, AssetBundle
}

public AssetBundle(CordovaResourceApi resourceApi, Uri directoryUri, AssetManifest manifest, AssetBundle parentAssetBundle) throws WebAppException {
Log.w(LOG_TAG, "Loading asset bundle from directory " + directoryUri.toString());
printDirectoryContent(new File(URI.create(directoryUri.toString())), true);

this.resourceApi = resourceApi;
this.directoryUri = directoryUri;
this.parentAssetBundle = parentAssetBundle;
Expand All @@ -95,12 +99,14 @@ public AssetBundle(CordovaResourceApi resourceApi, Uri directoryUri, AssetManife

if (parentAssetBundle == null || parentAssetBundle.cachedAssetForUrlPath(urlPath, entry.hash) == null) {
Asset asset = new Asset(entry.filePath, urlPath, entry.fileType, entry.cacheable, entry.hash, entry.sourceMapUrlPath);
Log.w(LOG_TAG, "Adding asset " + urlPath + " from filepath " + asset.getFileUri().toString());
addAsset(asset);
}

if (entry.sourceMapFilePath != null && entry.sourceMapUrlPath != null) {
if (parentAssetBundle == null || parentAssetBundle.cachedAssetForUrlPath(entry.sourceMapUrlPath, null) == null) {
Asset sourceMap = new Asset(entry.sourceMapFilePath, entry.sourceMapUrlPath, "json", true, null, null);
Log.w(LOG_TAG, "Adding asset " + urlPath + " from filepath " + sourceMap.getFileUri().toString());
addAsset(sourceMap);
}
}
Expand All @@ -115,14 +121,23 @@ protected void addAsset(Asset asset) {
ownAssetsByURLPath.put(asset.urlPath, asset);
}

public Uri getDirectoryUri() {
return directoryUri;
}

public Set<Asset> getOwnAssets() {
return new HashSet<Asset>(ownAssetsByURLPath.values());
}

public Asset assetForUrlPath(String urlPath) {
Asset asset = ownAssetsByURLPath.get(urlPath);
if (asset == null && parentAssetBundle != null) {
Log.w(LOG_TAG, "Asset " + urlPath + " not found in bundle " + version + ":" + directoryUri.toString() + ", going to parent bundle");
asset = parentAssetBundle.assetForUrlPath(urlPath);
} else if (asset == null) {
Log.w(LOG_TAG, "Asset " + urlPath + " not found in bundle " + version + ":" + directoryUri.toString() + ", no parent bundle");
} else {
Log.w(LOG_TAG, "Asset " + urlPath + " found in bundle " + version + ":" + directoryUri.toString());
}
return asset;
}
Expand All @@ -149,6 +164,7 @@ public String getCordovaCompatibilityVersion() {
}

public Asset getIndexFile() {
Log.w(LOG_TAG, "index.html found in bundle " + version + ":" + directoryUri.toString());
return indexFile;
}

Expand Down Expand Up @@ -237,4 +253,19 @@ private String stringFromUri(Uri uri) throws IOException {
}
}
}

static void printDirectoryContent(File folder, boolean recursive) {
if (folder.isDirectory() && folder.exists()) {
Log.w(LOG_TAG, "Directory " + folder.getAbsolutePath() + " content is:");
File[] allFiles = folder.listFiles();
for (File file : allFiles) {
Log.w(LOG_TAG, "\t" + file.getAbsolutePath());
if (recursive && file.isDirectory()) {
printDirectoryContent(file, true);
}
}
} else {
Log.w(LOG_TAG, "Directory " + folder.getAbsolutePath() + " doesnt exists");
}
}
}
16 changes: 14 additions & 2 deletions src/android/WebAppConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.meteor.webapp;

import android.content.SharedPreferences;
import android.util.Log;

import java.util.Collections;
import java.util.HashSet;
Expand Down Expand Up @@ -62,13 +63,24 @@ public void setLastKnownGoodVersion(String version) {
}

public Set<String> getBlacklistedVersions() {
return preferences.getStringSet("blacklistedVersions", Collections.EMPTY_SET);
Set<String> blacklistedVersions = preferences.getStringSet("blacklistedVersions", Collections.EMPTY_SET);
Log.d("BLACKLIST", "getBlacklistedVersions: " + blacklistedVersions);
return blacklistedVersions;
}

public void addBlacklistedVersion(String version) {
Set<String> blacklistedVersionForRetry = preferences.getStringSet("blacklistedVersionsForRetry", Collections.EMPTY_SET);
Set<String> blacklistedVersions = new HashSet<String>(getBlacklistedVersions());
blacklistedVersions.add(version);
preferences.edit().putStringSet("blacklistedVersions", blacklistedVersions).commit();

if (blacklistedVersionForRetry.isEmpty()) {
Log.d("BLACKLIST", "blacklisting version for retry: " + blacklistedVersions);
preferences.edit().putStringSet("blacklistedVersionsForRetry", blacklistedVersions).commit();
} else {
Log.d("BLACKLIST", "blacklisting version for real: " + blacklistedVersions);
preferences.edit().putStringSet("blacklistedVersionsForRetry", Collections.EMPTY_SET).commit();
preferences.edit().putStringSet("blacklistedVersions", blacklistedVersions).commit();
}
}

public void reset() {
Expand Down
71 changes: 70 additions & 1 deletion src/android/WebAppLocalServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@
import org.apache.cordova.Config;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.LOG;
import org.apache.cordova.PluginResult;
import org.json.JSONArray;
import org.json.JSONException;

import java.io.File;
import java.io.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.net.URI;

import okhttp3.HttpUrl;

Expand Down Expand Up @@ -124,9 +126,11 @@ public void pluginInitialize() {
void initializeAssetBundles() throws WebAppException {
// The initial asset bundle consists of the assets bundled with the app
AssetBundle initialAssetBundle = new AssetBundle(resourceApi, applicationDirectoryUri);
Log.w(LOG_TAG, "initial bundle loaded " + initialAssetBundle.getVersion());

// Downloaded versions are stored in /data/data/<app>/files/meteor
File versionsDirectory = new File(cordova.getActivity().getFilesDir(), "meteor");
printDirectoryContent(versionsDirectory, true);

// If the last seen initial version is different from the currently bundled
// version, we delete the versions directory and unset lastDownloadedVersion
Expand Down Expand Up @@ -184,6 +188,7 @@ public void onReset() {
}

Log.i(LOG_TAG, "Serving asset bundle with version: " + currentAssetBundle.getVersion());
printDirectoryContent(new File(URI.create(currentAssetBundle.getDirectoryUri().toString())), true);

configuration.setAppId(currentAssetBundle.getAppId());
configuration.setRootUrlString(currentAssetBundle.getRootUrlString());
Expand All @@ -195,6 +200,17 @@ public void onReset() {
}
}

private void switchPendingVersion(CallbackContext callbackContext) {
// If there is a pending asset bundle, we make it the current
if (pendingAssetBundle != null) {
Log.w(LOG_TAG, "Switching pending version " + pendingAssetBundle.getVersion() + " as current version.");
currentAssetBundle = pendingAssetBundle;
pendingAssetBundle = null;
}

callbackContext.success();
}

private void startStartupTimer() {
removeStartupTimer();

Expand Down Expand Up @@ -233,6 +249,9 @@ public boolean execute(String action, JSONArray args, CallbackContext callbackCo
} else if ("startupDidComplete".equals(action)) {
startupDidComplete(callbackContext);
return true;
} else if ("switchPendingVersion".equals(action)) {
switchPendingVersion(callbackContext);
return true;
}

if (testingDelegate != null) {
Expand Down Expand Up @@ -293,6 +312,8 @@ private void notifyError(Throwable cause) {
private void startupDidComplete(CallbackContext callbackContext) {
removeStartupTimer();

Log.w(LOG_TAG, "Startup completed received. New good version is " + currentAssetBundle.getVersion());

// If startup completed successfully, we consider a version good
configuration.setLastKnownGoodVersion(currentAssetBundle.getVersion());

Expand Down Expand Up @@ -373,6 +394,7 @@ public boolean shouldDownloadBundleForManifest(AssetManifest manifest) {

@Override
public void onFinishedDownloadingAssetBundle(AssetBundle assetBundle) {
Log.w(LOG_TAG, "Finished downloading " + assetBundle.getVersion());
configuration.setLastDownloadedVersion(assetBundle.getVersion());
pendingAssetBundle = assetBundle;
notifyNewVersionReady(assetBundle.getVersion());
Expand All @@ -395,8 +417,13 @@ private void initializeResourceHandlers() {
public Uri remapUri(Uri uri) {
if (currentAssetBundle == null) return null;

Log.w(LOG_TAG, "Requesting asset " + uri.toString());

AssetBundle.Asset asset = currentAssetBundle.assetForUrlPath(uri.getPath());
if (asset != null) {
if (asset.getFileUri().toString().endsWith("index.html")) {
printFileContent(asset.getFileUri());
}
return asset.getFileUri();
} else {
return null;
Expand Down Expand Up @@ -456,6 +483,8 @@ public Uri remapUri(Uri uri) {

AssetBundle.Asset asset = currentAssetBundle.getIndexFile();
if (asset != null) {
Log.w(LOG_TAG, "Serving index.html for uri " + uri.toString());
printFileContent(asset.getFileUri());
return asset.getFileUri();
} else {
return null;
Expand Down Expand Up @@ -503,5 +532,45 @@ void setTestingDelegate(TestingDelegate testingDelegate) {
this.testingDelegate = testingDelegate;
}

void printFileContent(Uri uri) {
File file = new File(URI.create(uri.toString()));
try {
printFileContent(file);
}catch(Exception e) {
Log.e(LOG_TAG, "Error while printing file content", e);
}
}

void printDirectoryContent(File folder, boolean recursive) {
if (folder.isDirectory() && folder.exists()) {
Log.w(LOG_TAG, "Directory " + folder.getAbsolutePath() + " content is:");
File[] allFiles = folder.listFiles();
for (File file : allFiles) {
Log.w(LOG_TAG, "\t" + file.getAbsolutePath());
if (recursive && file.isDirectory()) {
printDirectoryContent(file, true);
}
}
} else {
Log.w(LOG_TAG, "Directory " + folder.getAbsolutePath() + " doesnt exists");
}
}

public static void printStreamContent(InputStream is) throws Exception {
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
String line = null;
while ((line = reader.readLine()) != null) {
Log.w(LOG_TAG, line);
}
reader.close();
}

public static void printFileContent (File fl) throws Exception {
FileInputStream fin = new FileInputStream(fl);
printStreamContent(fin);
//Make sure you close all streams.
fin.close();
}

//endregion
}
38 changes: 25 additions & 13 deletions src/ios/WebAppConfiguration.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
final class WebAppConfiguration {
let userDefaults = UserDefaults.standard

/// The appId as defined in the runtime config
var appId: String? {
get {
Expand All @@ -12,13 +12,13 @@ final class WebAppConfiguration {
if oldValue != nil {
NSLog("appId seems to have changed, new: \(newValue!), old: \(oldValue!)")
}

userDefaults.set(newValue, forKey: "MeteorWebAppId")
userDefaults.synchronize()
}
}
}

/// The rootURL as defined in the runtime config
var rootURL: URL? {
get {
Expand All @@ -30,19 +30,19 @@ final class WebAppConfiguration {
if oldValue != nil {
NSLog("ROOT_URL seems to have changed, new: \(newValue!), old: \(oldValue!)")
}

userDefaults.set(newValue, forKey: "MeteorWebAppRootURL")
userDefaults.synchronize()
}
}
}

/// The Cordova compatibility version as specified in the asset manifest
var cordovaCompatibilityVersion: String? {
get {
return userDefaults.string(forKey: "MeteorWebAppCordovaCompatibilityVersion")
}

set {
if newValue != cordovaCompatibilityVersion {
if newValue == nil {
Expand All @@ -54,13 +54,13 @@ final class WebAppConfiguration {
}
}
}

/// The last seen initial version of the asset bundle
var lastSeenInitialVersion: String? {
get {
return userDefaults.string(forKey: "MeteorWebAppLastSeenInitialVersion")
}

set {
if newValue != lastSeenInitialVersion {
if newValue == nil {
Expand All @@ -72,7 +72,7 @@ final class WebAppConfiguration {
}
}
}

/// The last downloaded version of the asset bundle
var lastDownloadedVersion: String? {
get {
Expand Down Expand Up @@ -113,27 +113,39 @@ final class WebAppConfiguration {
/// Blacklisted asset bundle versions
var blacklistedVersions: [String] {
get {
return userDefaults.array(forKey: "MeteorWebAppBlacklistedVersions") as? [String] ?? []
let blvs = userDefaults.array(forKey: "MeteorWebAppBlacklistedVersions") as? [String] ?? []
print("BLACKLIST - getBlacklistedVersions: \(blvs)");
return blvs
}

set {
if newValue != blacklistedVersions {
if newValue.isEmpty {
print("BLACKLIST - removing blacklisted versions");
userDefaults.removeObject(forKey: "MeteorWebAppBlacklistedForRetry")
userDefaults.removeObject(forKey: "MeteorWebAppBlacklistedVersions")
} else {
userDefaults.set(newValue, forKey: "MeteorWebAppBlacklistedVersions")
let retryAttempted = userDefaults.object(forKey: "MeteorWebAppBlacklistedForRetry")
if retryAttempted == nil {
print("BLACKLIST - blacklisting version \(newValue) for retry");
userDefaults.set(newValue, forKey: "MeteorWebAppBlacklistedForRetry")
} else {
print("BLACKLIST - removing retry list and blacklisting \(newValue) for ever")
userDefaults.removeObject(forKey: "MeteorWebAppBlacklistedForRetry")
userDefaults.set(newValue, forKey: "MeteorWebAppBlacklistedVersions")
}
}
userDefaults.synchronize()
}
}
}

func addBlacklistedVersion(_ version: String) {
var blacklistedVersions = self.blacklistedVersions
blacklistedVersions.append(version)
self.blacklistedVersions = blacklistedVersions
}

func reset() {
cordovaCompatibilityVersion = nil
lastSeenInitialVersion = nil
Expand Down
Loading

0 comments on commit ef7b999

Please sign in to comment.