Skip to content
This repository has been archived by the owner on Aug 8, 2023. It is now read-only.

Commit

Permalink
[android] #3891 - bring callbacks into java via interfaces
Browse files Browse the repository at this point in the history
  • Loading branch information
zugaldia committed Feb 18, 2016
1 parent e2e0ed5 commit bb5d895
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package com.mapbox.mapboxsdk.offline;

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

import java.util.List;

Expand All @@ -24,6 +23,7 @@ public class OfflineManager {

public interface ListOfflineRegionsCallback {
void onList(List<OfflineRegion> offlineRegions);
void onError(String error);
}

public interface CreateOfflineRegionCallback {
Expand Down Expand Up @@ -61,7 +61,9 @@ public String getAccessToken() {
* of the SDK bindings to re-execute a user-provided callback on the main thread.
*/
public void listOfflineRegions(ListOfflineRegionsCallback callback) {

if (callback != null) {
listOfflineRegions(mDefaultFileSourcePtr, callback);
}
}

/**
Expand Down Expand Up @@ -89,4 +91,6 @@ public void createOfflineRegion(
private native long createDefaultFileSource(String cachePath, String assetRoot);
private native void setAccessToken(long defaultFileSourcePtr, String accessToken);
private native String getAccessToken(long defaultFileSourcePtr);
private native void listOfflineRegions(long defaultFileSourcePtr, ListOfflineRegionsCallback callback);

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,18 @@ public class OfflineActivity extends AppCompatActivity

private final static String LOG_TAG = "OfflineActivity";

/*
* UI elements
*/
private MapView mMapView;
private MapboxMap mMapboxMap;
private ProgressBar mProgressBar;
private Button downloadRegion;
private Button listRegions;

/*
* Offline objects
*/
private OfflineManager mOfflineManager;
private OfflineRegion mOfflineRegion;

Expand Down Expand Up @@ -210,6 +216,11 @@ public void onList(List<OfflineRegion> offlineRegions) {
listRegionsDialog.setArguments(args);
listRegionsDialog.show(getSupportFragmentManager(), "list");
}

@Override
public void onError(String error) {
Log.e(LOG_TAG, "Error: " + error);
}
});
}

Expand Down
92 changes: 91 additions & 1 deletion platform/android/src/jni.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mbgl/platform/log.hpp>
#include <mbgl/storage/network_status.hpp>
#include <mbgl/util/exception.hpp>
#include <mbgl/util/string.hpp>

#pragma clang diagnostic ignored "-Wunused-parameter"

Expand Down Expand Up @@ -118,6 +119,8 @@ jfieldID customLayerDeinitializeFunctionId = nullptr;
// Offline declarations start

jclass customOfflineManagerClass = nullptr;
jclass listOfflineRegionsCallbackClass = nullptr;
jmethodID onErrorMethodId = nullptr;

// Offline declarations end

Expand Down Expand Up @@ -1639,18 +1642,44 @@ jlong JNICALL createDefaultFileSource(JNIEnv *env, jobject obj, jstring cachePat

void JNICALL setAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jstring accessToken_) {
mbgl::Log::Debug(mbgl::Event::JNI, "setAccessToken");
assert(defaultFileSourcePtr != 0);
std::string accessToken = std_string_from_jstring(env, accessToken_);
mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast<mbgl::DefaultFileSource *>(defaultFileSourcePtr);
defaultFileSource->setAccessToken(accessToken);
}

jstring JNICALL getAccessToken(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr) {
mbgl::Log::Debug(mbgl::Event::JNI, "getAccessToken");
assert(defaultFileSourcePtr != 0);
mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast<mbgl::DefaultFileSource *>(defaultFileSourcePtr);
std::string accessToken = defaultFileSource->getAccessToken();
return std_string_to_jstring(env, accessToken);
}

void JNICALL listOfflineRegions(JNIEnv *env, jobject obj, jlong defaultFileSourcePtr, jobject callback) {
mbgl::Log::Debug(mbgl::Event::JNI, "listOfflineRegions");

// Checks
assert(defaultFileSourcePtr != 0);
if (callback == nullptr) {
mbgl::Log::Error(mbgl::Event::JNI, "Callback has to be set.");
return;
}

// Launch callback lambda
mbgl::DefaultFileSource *defaultFileSource = reinterpret_cast<mbgl::DefaultFileSource *>(defaultFileSourcePtr);
defaultFileSource->listOfflineRegions([&env, &callback](std::exception_ptr error, mbgl::optional<std::vector<mbgl::OfflineRegion>> regions) {
if (error) {
std::string message = mbgl::util::toString(error);
env->CallVoidMethod(callback, onErrorMethodId, std_string_to_jstring(env, message));
} else if (regions) {
for(std::vector<int>::size_type i = 0; i != regions->size(); i++) {
/* Handle regions */
}
}
});
}

// Offline calls end

}
Expand Down Expand Up @@ -2043,6 +2072,16 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->ExceptionDescribe();
}

listOfflineRegionsCallbackClass = env->FindClass("com/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback");
if (listOfflineRegionsCallbackClass == nullptr) {
env->ExceptionDescribe();
}

onErrorMethodId = env->GetMethodID(listOfflineRegionsCallbackClass, "onError", "(Ljava/lang/String;)V");
if (onErrorMethodId == nullptr) {
env->ExceptionDescribe();
}

// Offline definitions end

const std::vector<JNINativeMethod> methods = {
Expand Down Expand Up @@ -2186,7 +2225,8 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
const std::vector<JNINativeMethod> offlineMethods = {
{"createDefaultFileSource", "(Ljava/lang/String;Ljava/lang/String;)J", reinterpret_cast<void *>(&createDefaultFileSource)},
{"setAccessToken", "(JLjava/lang/String;)V", reinterpret_cast<void *>(&setAccessToken)},
{"getAccessToken", "(J)Ljava/lang/String;", reinterpret_cast<void *>(&getAccessToken)}
{"getAccessToken", "(J)Ljava/lang/String;", reinterpret_cast<void *>(&getAccessToken)},
{"listOfflineRegions", "(JLcom/mapbox/mapboxsdk/offline/OfflineManager$ListOfflineRegionsCallback;)V", reinterpret_cast<void *>(&listOfflineRegions)}
};

if (env->RegisterNatives(customOfflineManagerClass, offlineMethods.data(), offlineMethods.size()) < 0) {
Expand Down Expand Up @@ -2370,6 +2410,48 @@ extern "C" JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
env->DeleteGlobalRef(httpContextClass);
}

// Offline global definitions begin

customOfflineManagerClass = reinterpret_cast<jclass>(env->NewGlobalRef(customOfflineManagerClass));
if (customOfflineManagerClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngBoundsClass);
env->DeleteGlobalRef(iconClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(httpRequestClass);
}

listOfflineRegionsCallbackClass = reinterpret_cast<jclass>(env->NewGlobalRef(listOfflineRegionsCallbackClass));
if (listOfflineRegionsCallbackClass == nullptr) {
env->ExceptionDescribe();
env->DeleteGlobalRef(latLngClass);
env->DeleteGlobalRef(latLngBoundsClass);
env->DeleteGlobalRef(iconClass);
env->DeleteGlobalRef(markerClass);
env->DeleteGlobalRef(polylineClass);
env->DeleteGlobalRef(polygonClass);
env->DeleteGlobalRef(runtimeExceptionClass);
env->DeleteGlobalRef(nullPointerExceptionClass);
env->DeleteGlobalRef(arrayListClass);
env->DeleteGlobalRef(projectedMetersClass);
env->DeleteGlobalRef(pointFClass);
env->DeleteGlobalRef(rectFClass);
env->DeleteGlobalRef(httpContextClass);
env->DeleteGlobalRef(customOfflineManagerClass);
}

// Offline global definitions end

char release[PROP_VALUE_MAX] = "";
__system_property_get("ro.build.version.release", release);
androidRelease = std::string(release);
Expand Down Expand Up @@ -2472,6 +2554,14 @@ extern "C" JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {
httpRequestStartId = nullptr;
httpRequestCancelId = nullptr;

// Offline delete begins

env->DeleteGlobalRef(customOfflineManagerClass);
env->DeleteGlobalRef(listOfflineRegionsCallbackClass);
onErrorMethodId = nullptr;

// Offline delete ends

theJVM = nullptr;
}
}
4 changes: 4 additions & 0 deletions platform/android/src/jni.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@ extern jclass httpRequestClass;
extern jmethodID httpRequestStartId;
extern jmethodID httpRequestCancelId;

extern jclass customOfflineManagerClass;
extern jclass listOfflineRegionsCallbackClass;
extern jmethodID onErrorMethodId;

extern bool throw_jni_error(JNIEnv *env, const char *msg);
extern bool attach_jni_thread(JavaVM* vm, JNIEnv** env, std::string threadName);
extern void detach_jni_thread(JavaVM* vm, JNIEnv** env, bool detach);
Expand Down

0 comments on commit bb5d895

Please sign in to comment.