diff options
9 files changed, 278 insertions, 120 deletions
diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java new file mode 100644 index 0000000000..2ae37acb9c --- /dev/null +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/AttributionDialogManager.java @@ -0,0 +1,169 @@ +package com.mapbox.mapboxsdk.maps; + +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.v7.app.AlertDialog; +import android.text.Html; +import android.text.SpannableStringBuilder; +import android.text.TextUtils; +import android.text.style.URLSpan; +import android.view.View; +import android.widget.ArrayAdapter; + +import com.mapbox.mapboxsdk.R; +import com.mapbox.mapboxsdk.camera.CameraPosition; +import com.mapbox.mapboxsdk.style.sources.Source; +import com.mapbox.services.android.telemetry.MapboxTelemetry; + +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.Locale; + +/** + * Responsible for managing attribution interactions on the map. + * <p> + * When the user clicks the attribution icon, {@link AttributionDialogManager#onClick(View)} will be invoked. + * An attribution dialog will be shown to the user with contents based on the attributions found in the map style. + * Additionally an telemetry option item is shown to configure telemetry settings. + * </p> + */ +class AttributionDialogManager implements View.OnClickListener, DialogInterface.OnClickListener { + + private static final String MAP_FEEDBACK_URL = "https://www.mapbox.com/map-feedback"; + private static final String MAP_FEEDBACK_LOCATION_FORMAT = MAP_FEEDBACK_URL + "/#/%f/%f/%d"; + + private final Context context; + private final MapboxMap mapboxMap; + private String[] attributionKeys; + private HashMap<String, String> attributionMap; + + AttributionDialogManager(@NonNull Context context, @NonNull MapboxMap mapboxMap) { + this.context = context; + this.mapboxMap = mapboxMap; + } + + // Called when someone presses the attribution icon on the map + @Override + public void onClick(View view) { + attributionMap = new AttributionBuilder(context, mapboxMap).build(); + showAttributionDialog(); + } + + private void showAttributionDialog() { + attributionKeys = attributionMap.keySet().toArray(new String[attributionMap.size()]); + AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle); + builder.setTitle(R.string.mapbox_attributionsDialogTitle); + builder.setAdapter(new ArrayAdapter<>(context, R.layout.mapbox_attribution_list_item, attributionKeys), this); + builder.show(); + } + + // Called when someone selects an attribution or telemetry settings from the dialog + @Override + public void onClick(DialogInterface dialog, int which) { + if (isLatestEntry(which)) { + showTelemetryDialog(); + } else { + showAttributionWebPage(which); + } + } + + private boolean isLatestEntry(int attributionKeyIndex) { + return attributionKeyIndex == attributionKeys.length - 1; + } + + private void showTelemetryDialog() { + AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle); + builder.setTitle(R.string.mapbox_attributionTelemetryTitle); + builder.setMessage(R.string.mapbox_attributionTelemetryMessage); + builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + MapboxTelemetry.getInstance().setTelemetryEnabled(true); + dialog.cancel(); + } + }); + builder.setNeutralButton(R.string.mapbox_attributionTelemetryNeutral, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + String url = context.getResources().getString(R.string.mapbox_telemetryLink); + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.setData(Uri.parse(url)); + context.startActivity(intent); + dialog.cancel(); + } + }); + builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + MapboxTelemetry.getInstance().setTelemetryEnabled(false); + dialog.cancel(); + } + }); + builder.show(); + } + + private void showAttributionWebPage(int which) { + Intent intent = new Intent(Intent.ACTION_VIEW); + String url = attributionMap.get(attributionKeys[which]); + if (url.contains(MAP_FEEDBACK_URL)) { + url = buildMapFeedbackMapUrl(mapboxMap.getCameraPosition()); + } + intent.setData(Uri.parse(url)); + context.startActivity(intent); + } + + private String buildMapFeedbackMapUrl(CameraPosition cameraPosition) { + // appends current location to the map feedback url if available + return cameraPosition != null ? String.format(Locale.getDefault(), + MAP_FEEDBACK_LOCATION_FORMAT, cameraPosition.target.getLongitude(), cameraPosition.target.getLatitude(), + (int) cameraPosition.zoom) : MAP_FEEDBACK_URL; + } + + private static class AttributionBuilder { + + private final HashMap<String, String> map = new LinkedHashMap<>(); + private final Context context; + private final MapboxMap mapboxMap; + + AttributionBuilder(Context context, MapboxMap mapboxMap) { + this.context = context.getApplicationContext(); + this.mapboxMap = mapboxMap; + } + + private HashMap<String, String> build() { + for (Source source : mapboxMap.getSources()) { + parseAttribution(source.getAttribution()); + } + addTelemetryEntryToAttributionMap(); + return map; + } + + private void parseAttribution(String attributionSource) { + if (!TextUtils.isEmpty(attributionSource)) { + SpannableStringBuilder htmlBuilder = (SpannableStringBuilder) Html.fromHtml(attributionSource); + URLSpan[] urlSpans = htmlBuilder.getSpans(0, htmlBuilder.length(), URLSpan.class); + for (URLSpan urlSpan : urlSpans) { + map.put(resolveAnchorValue(htmlBuilder, urlSpan), urlSpan.getURL()); + } + } + } + + private String resolveAnchorValue(SpannableStringBuilder htmlBuilder, URLSpan urlSpan) { + int start = htmlBuilder.getSpanStart(urlSpan); + int end = htmlBuilder.getSpanEnd(urlSpan); + int length = end - start; + char[] charKey = new char[length]; + htmlBuilder.getChars(start, end, charKey, 0); + return String.valueOf(charKey); + } + + private void addTelemetryEntryToAttributionMap() { + String telemetryKey = context.getString(R.string.mapbox_telemetrySettings); + String telemetryLink = context.getString(R.string.mapbox_telemetryLink); + map.put(telemetryKey, telemetryLink); + } + } +} diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java index 8c8b70d788..46db93fa28 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/maps/MapView.java @@ -1,15 +1,11 @@ package com.mapbox.mapboxsdk.maps; import android.app.Activity; -import android.app.Dialog; import android.app.Fragment; import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; import android.graphics.Canvas; import android.graphics.PointF; import android.graphics.SurfaceTexture; -import android.net.Uri; import android.os.Bundle; import android.os.Handler; import android.support.annotation.CallSuper; @@ -17,7 +13,6 @@ import android.support.annotation.IntDef; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.UiThread; -import android.support.v7.app.AlertDialog; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -28,7 +23,6 @@ import android.view.SurfaceView; import android.view.TextureView; import android.view.View; import android.view.ViewGroup; -import android.widget.ArrayAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ZoomButtonsController; @@ -36,7 +30,6 @@ import android.widget.ZoomButtonsController; import com.mapbox.mapboxsdk.Mapbox; import com.mapbox.mapboxsdk.R; import com.mapbox.mapboxsdk.annotations.MarkerViewManager; -import com.mapbox.mapboxsdk.camera.CameraPosition; import com.mapbox.mapboxsdk.constants.MapboxConstants; import com.mapbox.mapboxsdk.constants.Style; import com.mapbox.mapboxsdk.maps.widgets.CompassView; @@ -155,7 +148,7 @@ public class MapView extends FrameLayout { // inject widgets with MapboxMap compassView.setMapboxMap(mapboxMap); myLocationView.setMapboxMap(mapboxMap); - attrView.setOnClickListener(new AttributionOnClickListener(context, transform)); + attrView.setOnClickListener(new AttributionDialogManager(context, mapboxMap)); // Ensure this view is interactable setClickable(true); @@ -593,78 +586,6 @@ public class MapView extends FrameLayout { this.mapboxMap = mapboxMap; } - private static class AttributionOnClickListener implements View.OnClickListener, DialogInterface.OnClickListener { - - private static final int ATTRIBUTION_INDEX_IMPROVE_THIS_MAP = 2; - private static final int ATTRIBUTION_INDEX_TELEMETRY_SETTINGS = 3; - private Context context; - private Transform transform; - - public AttributionOnClickListener(Context context, Transform transform) { - this.context = context; - this.transform = transform; - } - - // Called when someone presses the attribution icon - @Override - public void onClick(View view) { - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle); - builder.setTitle(R.string.mapbox_attributionsDialogTitle); - String[] items = context.getResources().getStringArray(R.array.mapbox_attribution_names); - builder.setAdapter(new ArrayAdapter<>(context, R.layout.mapbox_attribution_list_item, items), this); - builder.show(); - } - - // Called when someone selects an attribution, 'Improve this map' adds location data to the url - @Override - public void onClick(DialogInterface dialog, int which) { - final Context context = ((Dialog) dialog).getContext(); - if (which == ATTRIBUTION_INDEX_TELEMETRY_SETTINGS) { - AlertDialog.Builder builder = new AlertDialog.Builder(context, R.style.mapbox_AlertDialogStyle); - builder.setTitle(R.string.mapbox_attributionTelemetryTitle); - builder.setMessage(R.string.mapbox_attributionTelemetryMessage); - builder.setPositiveButton(R.string.mapbox_attributionTelemetryPositive, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - MapboxTelemetry.getInstance().setTelemetryEnabled(true); - dialog.cancel(); - } - }); - builder.setNeutralButton(R.string.mapbox_attributionTelemetryNeutral, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - String url = context.getResources().getStringArray(R.array.mapbox_attribution_links)[3]; - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - context.startActivity(intent); - dialog.cancel(); - } - }); - builder.setNegativeButton(R.string.mapbox_attributionTelemetryNegative, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - MapboxTelemetry.getInstance().setTelemetryEnabled(false); - dialog.cancel(); - } - }); - - builder.show(); - return; - } - String url = context.getResources().getStringArray(R.array.mapbox_attribution_links)[which]; - if (which == ATTRIBUTION_INDEX_IMPROVE_THIS_MAP) { - CameraPosition cameraPosition = transform.getCameraPosition(); - if (cameraPosition != null) { - url = String.format(url, cameraPosition.target.getLongitude(), - cameraPosition.target.getLatitude(), (int) cameraPosition.zoom); - } - } - Intent intent = new Intent(Intent.ACTION_VIEW); - intent.setData(Uri.parse(url)); - context.startActivity(intent); - } - } - /** * Definition of a map change event. * diff --git a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java index 62bfcb818f..22b2244537 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java +++ b/platform/android/MapboxGLAndroidSDK/src/main/java/com/mapbox/mapboxsdk/style/sources/Source.java @@ -28,6 +28,18 @@ public abstract class Source { } /** + * Retrieve the source attribution. + * <p> + * Will return an empty String if no attribution is available. + * </p> + * + * @return the string representation of the attribution in html format + */ + public String getAttribution() { + return nativeGetAttribution(); + } + + /** * Internal use * * @return the native peer pointer @@ -38,4 +50,6 @@ public abstract class Source { protected native String nativeGetId(); + protected native String nativeGetAttribution(); + } diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml index a64fad39c2..fe94d82baa 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res-public/values/public.xml @@ -89,7 +89,7 @@ <public name="mapbox_style_satellite" type="string" /> <public name="mapbox_style_satellite_streets" type="string" /> - <!-- Exposed error messages --> + <!-- Exposed strings --> <public name="mapbox_compassContentDescription" type="string" /> <public name="mapbox_attributionsIconContentDescription" type="string" /> <public name="mapbox_myLocationViewContentDescription" type="string" /> @@ -100,6 +100,7 @@ <public name="mapbox_attributionTelemetryPositive" type="string" /> <public name="mapbox_attributionTelemetryNegative" type="string" /> <public name="mapbox_attributionTelemetryNeutral" type="string" /> + <public name="mapbox_telemetrySettings" type="string"/> <public name="mapbox_offline_error_region_definition_invalid" type="string" /> <!-- Exposed drawables --> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml deleted file mode 100644 index 5a5fd6cb4c..0000000000 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/arrays.xml +++ /dev/null @@ -1,16 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <array name="mapbox_attribution_names"> - <item>© Mapbox</item> - <item>© OpenStreetMap</item> - <item>Improve this map</item> - <item>Telemetry Settings</item> - </array> - <!-- If editing this array update MapView.ATTRIBUTION_INDEX_IMPROVE_THIS_MAP --> - <array name="mapbox_attribution_links" formatted="false" translatable="false"> - <item>https://www.mapbox.com/about/maps/</item> - <item>http://www.openstreetmap.org/about/</item> - <item>https://www.mapbox.com/map-feedback/#/%1$f/%2$f/%3$d</item> - <item>https://www.mapbox.com/telemetry/</item> - </array> -</resources> diff --git a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml index cf7707d37e..6c427d540b 100644 --- a/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml +++ b/platform/android/MapboxGLAndroidSDK/src/main/res/values/strings.xml @@ -11,6 +11,8 @@ <string name="mapbox_attributionTelemetryNegative">Disagree</string> <string name="mapbox_attributionTelemetryNeutral">More info</string> <string name="mapbox_offline_error_region_definition_invalid">Provided OfflineRegionDefinition doesn\'t fit the world bounds: %s</string> + <string name="mapbox_telemetrySettings">Telemetry Settings</string> + <string name="mapbox_telemetryLink" translatable="false">https://www.mapbox.com/telemetry/</string> <!-- these are public --> <!-- Using one of these constants means your map style will always use the latest version and diff --git a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java index fa1451092a..1c225204e5 100644 --- a/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java +++ b/platform/android/MapboxGLAndroidSDKTestApp/src/androidTest/java/com/mapbox/mapboxsdk/testapp/maps/widgets/AttributionTest.java @@ -8,9 +8,14 @@ import android.support.test.espresso.UiController; import android.support.test.espresso.ViewAction; import android.support.test.espresso.intent.Intents; import android.support.test.rule.ActivityTestRule; +import android.text.Html; +import android.text.SpannableStringBuilder; +import android.text.TextUtils; +import android.text.style.URLSpan; import android.view.View; import com.mapbox.mapboxsdk.maps.MapboxMap; +import com.mapbox.mapboxsdk.style.sources.Source; import com.mapbox.mapboxsdk.testapp.R; import com.mapbox.mapboxsdk.testapp.activity.espresso.EspressoTestActivity; import com.mapbox.mapboxsdk.testapp.utils.OnMapReadyIdlingResource; @@ -22,6 +27,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import static android.support.test.espresso.Espresso.onData; import static android.support.test.espresso.Espresso.onView; import static android.support.test.espresso.action.ViewActions.click; import static android.support.test.espresso.assertion.ViewAssertions.matches; @@ -32,7 +38,8 @@ import static android.support.test.espresso.intent.matcher.IntentMatchers.hasDat import static android.support.test.espresso.matcher.ViewMatchers.isDisplayed; import static android.support.test.espresso.matcher.ViewMatchers.withId; import static android.support.test.espresso.matcher.ViewMatchers.withText; -import static org.hamcrest.Matchers.allOf; +import static org.hamcrest.CoreMatchers.allOf; +import static org.hamcrest.CoreMatchers.anything; import static org.hamcrest.core.IsNot.not; public class AttributionTest { @@ -42,23 +49,32 @@ public class AttributionTest { private OnMapReadyIdlingResource idlingResource; - private String[] dialogTexts; - private String[] dialogLinks; + private MapboxMap mapboxMap; + private URLSpan[] urlSpans; @Before public void beforeTest() { idlingResource = new OnMapReadyIdlingResource(rule.getActivity()); Espresso.registerIdlingResources(idlingResource); Intents.init(); - dialogTexts = rule.getActivity().getResources().getStringArray(R.array.mapbox_attribution_names); - dialogLinks = rule.getActivity().getResources().getStringArray(R.array.mapbox_attribution_links); + ViewUtils.checkViewIsDisplayed(R.id.mapView); + mapboxMap = rule.getActivity().getMapboxMap(); + onView(withId(R.id.mapView)).perform(new MapboxMapAction(new InvokeViewAction() { + @Override + public void onViewAction(UiController uiController, View view) { + for (Source source : mapboxMap.getSources()) { + String attributionSource = source.getAttribution(); + if (!TextUtils.isEmpty(attributionSource)) { + SpannableStringBuilder htmlBuilder = (SpannableStringBuilder) Html.fromHtml(attributionSource); + urlSpans = htmlBuilder.getSpans(0, htmlBuilder.length(), URLSpan.class); + } + } + } + })); } @Test public void testDisabled() { - ViewUtils.checkViewIsDisplayed(R.id.mapView); - MapboxMap mapboxMap = rule.getActivity().getMapboxMap(); - // Default onView(withId(R.id.attributionView)).check(matches(isDisplayed())); @@ -69,46 +85,61 @@ public class AttributionTest { } @Test - public void testMapboxLink() { + public void testMapboxStreetsMapboxAttributionLink() { ViewUtils.checkViewIsDisplayed(R.id.mapView); + if (urlSpans == null) { + return; + } // click on View to open dialog onView(withId(R.id.attributionView)).perform(click()); onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed())); - // click on link and validate browser opening - Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[0]))); + // test for trigger url intent + Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(urlSpans[0].getURL()))); intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null)); - onView(withText(dialogTexts[0])).perform(click()); + + // click item and test for url + onData(anything()).inAdapterView(withId(R.id.select_dialog_listview)).atPosition(0).perform(click()); intended(expectedIntent); } @Test - public void testOpenStreetMapLink() { + public void testMapboxStreetsOpenStreetMapAttributionLink() { ViewUtils.checkViewIsDisplayed(R.id.mapView); - + if (urlSpans == null) { + return; + } // click on View to open dialog onView(withId(R.id.attributionView)).perform(click()); onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed())); - // click on link and validate browser opening - Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[1]))); + // test for trigger url intent + Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(urlSpans[1].getURL()))); intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null)); - onView(withText(dialogTexts[1])).perform(click()); + + // click item and test for url + onData(anything()).inAdapterView(withId(R.id.select_dialog_listview)).atPosition(1).perform(click()); + intended(expectedIntent); } @Test public void testImproveMapLink() { ViewUtils.checkViewIsDisplayed(R.id.mapView); - + if (urlSpans == null) { + return; + } // click on View to open dialog onView(withId(R.id.attributionView)).perform(click()); onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed())); - // click on Mapbox link and validate browser opening - Matcher<Intent> expectedIntent = allOf(hasAction(Intent.ACTION_VIEW), hasData(Uri.parse(dialogLinks[3]))); + // test for trigger url intent + Matcher<Intent> expectedIntent = hasAction(Intent.ACTION_VIEW); intending(expectedIntent).respondWith(new Instrumentation.ActivityResult(0, null)); - onView(withText(dialogTexts[3])).perform(click()); + + // click item and test for url + onData(anything()).inAdapterView(withId(R.id.select_dialog_listview)).atPosition(2).perform(click()); + intended(expectedIntent); } @Test @@ -120,7 +151,7 @@ public class AttributionTest { onView(withText(R.string.mapbox_attributionsDialogTitle)).check(matches(isDisplayed())); // click on item to open second dialog - onView(withText(dialogTexts[3])).perform(click()); + onView(withText(R.string.mapbox_telemetrySettings)).perform(click()); onView(withText(R.string.mapbox_attributionTelemetryTitle)).check(matches(isDisplayed())); } @@ -153,4 +184,32 @@ public class AttributionTest { mapboxMap.getUiSettings().setAttributionEnabled(false); } } + + private class MapboxMapAction implements ViewAction { + + private InvokeViewAction invokeViewAction; + + MapboxMapAction(InvokeViewAction invokeViewAction) { + this.invokeViewAction = invokeViewAction; + } + + @Override + public Matcher<View> getConstraints() { + return isDisplayed(); + } + + @Override + public String getDescription() { + return getClass().getSimpleName(); + } + + @Override + public void perform(UiController uiController, View view) { + invokeViewAction.onViewAction(uiController, view); + } + } + + interface InvokeViewAction { + void onViewAction(UiController uiController, View view); + } } diff --git a/platform/android/src/style/sources/source.cpp b/platform/android/src/style/sources/source.cpp index b780de5627..e0e9bb9870 100644 --- a/platform/android/src/style/sources/source.cpp +++ b/platform/android/src/style/sources/source.cpp @@ -43,6 +43,11 @@ namespace android { return jni::Make<jni::String>(env, source.getID()); } + jni::String Source::getAttribution(jni::JNIEnv& env) { + auto attribution = source.getAttribution(); + return attribution ? jni::Make<jni::String>(env, attribution.value()) : jni::Make<jni::String>(env,""); + } + void Source::addToMap(mbgl::Map& _map) { // Check to see if we own the source first if (!ownedSource) { @@ -71,7 +76,8 @@ namespace android { // Register the peer jni::RegisterNativePeer<Source>(env, Source::javaClass, "nativePtr", - METHOD(&Source::getId, "nativeGetId") + METHOD(&Source::getId, "nativeGetId"), + METHOD(&Source::getAttribution, "nativeGetAttribution") ); } diff --git a/platform/android/src/style/sources/source.hpp b/platform/android/src/style/sources/source.hpp index 9a9d504d68..49fc50d754 100644 --- a/platform/android/src/style/sources/source.hpp +++ b/platform/android/src/style/sources/source.hpp @@ -45,6 +45,8 @@ public: jni::String getId(jni::JNIEnv&); + jni::String getAttribution(jni::JNIEnv&); + protected: // Release the owned view and return it std::unique_ptr<mbgl::style::Source> releaseCoreSource(); |