Merge pull request #571 from atarsha/Add-MGLOfflinePackState

Expose OfflineRegion/OfflinePack pack state in progress object and add resume/suspend offline download support
This commit is contained in:
Nick Italiano
2017-08-29 11:50:41 -07:00
committed by GitHub
6 changed files with 293 additions and 16 deletions
@@ -56,6 +56,14 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
private static final String TAG = ReactNativeMapboxGLModule.class.getSimpleName();
private static final int ANDROID_SDK_OFFLINE_PACK_STATE_INACTIVE = 0;
private static final int ANDROID_SDK_OFFLINE_PACK_STATE_ACTIVE = 1;
private static final int OFFLINE_PACK_STATE_UNKNOWN = 0;
private static final int OFFLINE_PACK_STATE_INACTIVE = 1;
private static final int OFFLINE_PACK_STATE_ACTIVE = 2;
private static final int OFFLINE_PACK_STATE_COMPLETE = 3;
private ReactApplicationContext context;
private ReactNativeMapboxGLPackage aPackage;
Handler mainHandler;
@@ -105,6 +113,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
HashMap<String, Object> userTrackingMode = new HashMap<String, Object>();
HashMap<String, Object> mapStyles = new HashMap<String, Object>();
HashMap<String, Object> userLocationVerticalAlignment = new HashMap<String, Object>();
HashMap<String, Object> offlinePackState = new HashMap<String, Object>();
// User tracking constants
userTrackingMode.put("none", 0);
@@ -125,6 +134,13 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
userLocationVerticalAlignment.put("top", 1);
userLocationVerticalAlignment.put("bottom", 2);
// Offline Pack State constants
offlinePackState.put("unknown", 0);
offlinePackState.put("inactive", 1);
offlinePackState.put("active", 2);
offlinePackState.put("complete", 3);
offlinePackState.put("invalid", 4);
// Other constants
constants.put("unknownResourceCount", Long.MAX_VALUE);
constants.put("metricsEnabled", MapboxEventManager.getMapboxEventManager().isTelemetryEnabled());
@@ -132,6 +148,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
constants.put("userTrackingMode", userTrackingMode);
constants.put("mapStyles", mapStyles);
constants.put("userLocationVerticalAlignment", userLocationVerticalAlignment);
constants.put("offlinePackState", offlinePackState);
return constants;
}
@@ -347,6 +364,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
e.printStackTrace();
}
result.putInt("state", normalizeOfflineRegionState(status));
result.putInt("countOfBytesCompleted", (int)status.getCompletedResourceSize());
result.putInt("countOfResourcesCompleted", (int)status.getCompletedResourceCount());
result.putInt("countOfResourcesExpected", (int)status.getRequiredResourceCount());
@@ -355,6 +373,43 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
return result;
}
/*
* Normalizes offline region status state for the sake of parity with iOS for React Native
* Essentially we force Android state to be the same as iOS state for ease of cross-platform development
*
* On iOS:
* 0: Unknown
* 1: Inactive
* 2: Active
* 3: Complete
* 4: Invalid (iOS ONLY)
*
* On Android:
* 0: Inactive (Complete is inactive, AND countOfResourcesCompleted == countOfResourcesExpected)
* 1: Active
*/
static int normalizeOfflineRegionState(OfflineRegionStatus status) {
int state = (int)status.getDownloadState();
boolean isComplete = (boolean)status.isComplete();
switch (state) {
case ANDROID_SDK_OFFLINE_PACK_STATE_INACTIVE:
if (isComplete) {
state = OFFLINE_PACK_STATE_COMPLETE;
} else {
state = OFFLINE_PACK_STATE_INACTIVE;
}
break;
case ANDROID_SDK_OFFLINE_PACK_STATE_ACTIVE:
state = OFFLINE_PACK_STATE_ACTIVE;
break;
default:
state = OFFLINE_PACK_STATE_UNKNOWN;
}
return state;
}
static String getOfflineRegionName(OfflineRegion region) {
try {
ByteArrayInputStream bis = new ByteArrayInputStream(region.getMetadata());
@@ -489,14 +544,7 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
mainHandler.post(new Runnable() {
@Override
public void run() {
OfflineRegionProgressObserver foundObserver = null;
for (OfflineRegionProgressObserver observer : offlinePackObservers) {
if (packName.equals(observer.name)) {
foundObserver = observer;
break;
}
}
final OfflineRegionProgressObserver foundObserver = getObserver(packName);
if (foundObserver == null) {
promise.resolve(Arguments.createMap());
@@ -506,13 +554,11 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
offlinePackObservers.remove(foundObserver);
foundObserver.invalidate();
foundObserver.region.setDownloadState(OfflineRegion.STATE_INACTIVE);
final OfflineRegionProgressObserver _foundObserver = foundObserver;
foundObserver.region.delete(new OfflineRegion.OfflineRegionDeleteCallback() {
@Override
public void onDelete() {
WritableMap result = Arguments.createMap();
result.putString("deleted", _foundObserver.name);
result.putString("deleted", foundObserver.name);
promise.resolve(result);
}
@@ -525,6 +571,81 @@ public class ReactNativeMapboxGLModule extends ReactContextBaseJavaModule {
});
}
@ReactMethod
public void suspendOfflinePack(final String packName, final Promise promise) {
mainHandler.post(new Runnable() {
@Override
public void run() {
final OfflineRegionProgressObserver foundObserver = getObserver(packName);
if (foundObserver == null) {
promise.resolve(Arguments.createMap());
return;
}
foundObserver.region.setDownloadState(OfflineRegion.STATE_INACTIVE);
foundObserver.region.getStatus(new OfflineRegion.OfflineRegionStatusCallback() {
@Override
public void onStatus(OfflineRegionStatus status) {
foundObserver.onStatusChanged(status);
WritableMap result = Arguments.createMap();
result.putString("suspended", foundObserver.name);
promise.resolve(result);
}
@Override
public void onError(String error) {
Log.e(context.getApplicationContext().getPackageName(), error);
promise.reject(new JSApplicationIllegalArgumentException(error));
}
});
}
});
}
@ReactMethod
public void resumeOfflinePack(final String packName, final Promise promise) {
mainHandler.post(new Runnable() {
@Override
public void run() {
final OfflineRegionProgressObserver foundObserver = getObserver(packName);
if (foundObserver == null) {
promise.resolve(Arguments.createMap());
return;
}
foundObserver.region.setDownloadState(OfflineRegion.STATE_ACTIVE);
foundObserver.region.getStatus(new OfflineRegion.OfflineRegionStatusCallback() {
@Override
public void onStatus(OfflineRegionStatus status) {
foundObserver.onStatusChanged(status);
WritableMap result = Arguments.createMap();
result.putString("resumed", foundObserver.name);
promise.resolve(result);
}
@Override
public void onError(String error) {
Log.e(context.getApplicationContext().getPackageName(), error);
promise.reject(new JSApplicationIllegalArgumentException(error));
}
});
}
});
}
OfflineRegionProgressObserver getObserver(String name) {
OfflineRegionProgressObserver foundObserver = null;
for (OfflineRegionProgressObserver observer : offlinePackObservers) {
if (name.equals(observer.name)) {
foundObserver = observer;
break;
}
}
return foundObserver;
}
// Offline throttle control
@ReactMethod