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

Commit

Permalink
[android] ensure location shadow's gradient is greater than 0
Browse files Browse the repository at this point in the history
  • Loading branch information
LukasPaczos authored and Łukasz Paczos committed Jul 11, 2019
1 parent 5b02434 commit afa7cea
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,24 @@
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.graphics.drawable.LayerDrawable;
import android.location.Location;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.mapbox.mapboxsdk.geometry.LatLng;
import com.mapbox.mapboxsdk.log.Logger;
import com.mapbox.mapboxsdk.maps.MapboxMap;
import com.mapbox.mapboxsdk.maps.Projection;

import static com.mapbox.mapboxsdk.location.LocationComponentConstants.INSTANT_LOCATION_TRANSITION_THRESHOLD;

public final class Utils {

private static final String TAG = "Mbgl-com.mapbox.mapboxsdk.location.Utils";

private Utils() {
// Class should not be initialized
}
Expand Down Expand Up @@ -52,12 +58,42 @@ static Bitmap generateShadow(Drawable drawable, float elevation) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
try {
drawable.draw(canvas);
} catch (IllegalArgumentException ex) {
if (ex.getMessage().equals("radius must be > 0") && Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Logger.w(TAG,
"Location's shadow gradient drawable has a radius <= 0px, resetting to 1px in order to avoid crashing");
ensureShadowGradientRadius(drawable);
return generateShadow(drawable, elevation);
} else {
throw ex;
}
}
bitmap = Bitmap.createScaledBitmap(bitmap,
toEven(width + elevation), toEven(height + elevation), false);
return bitmap;
}

/**
* We need to ensure that the radius of any {@link GradientDrawable} is greater than 0 for API levels < 21.
*
* @see <a href=https://github.com/mapbox/mapbox-gl-native/issues/15026>mapbox-gl-native-#15026</a>
*/
private static void ensureShadowGradientRadius(Drawable drawable) {
if (drawable instanceof GradientDrawable) {
((GradientDrawable) drawable).setGradientRadius(1);
} else if (drawable instanceof LayerDrawable) {
LayerDrawable layerDrawable = (LayerDrawable) drawable;
for (int i = 0; i < layerDrawable.getNumberOfLayers(); i++) {
Drawable layers = layerDrawable.getDrawable(i);
if (layers instanceof GradientDrawable) {
((GradientDrawable) layers).setGradientRadius(1);
}
}
}
}

static float calculateZoomLevelRadius(@NonNull MapboxMap mapboxMap, @Nullable Location location) {
if (location == null) {
return 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package com.mapbox.mapboxsdk.location

import android.Manifest
import android.R
import android.content.Context
import android.location.Location
import android.support.test.annotation.UiThreadTest
import android.support.test.espresso.Espresso.onView
import android.support.test.espresso.IdlingRegistry
import android.support.test.espresso.UiController
Expand All @@ -23,8 +23,10 @@ import com.mapbox.mapboxsdk.location.utils.MapboxTestingUtils.Companion.pushSour
import com.mapbox.mapboxsdk.maps.MapboxMap
import com.mapbox.mapboxsdk.maps.Style
import com.mapbox.mapboxsdk.style.sources.GeoJsonSource
import com.mapbox.mapboxsdk.testapp.R
import com.mapbox.mapboxsdk.testapp.activity.EspressoTest
import com.mapbox.mapboxsdk.testapp.utils.TestingAsyncUtils
import com.mapbox.mapboxsdk.utils.BitmapUtils
import org.hamcrest.CoreMatchers.`is`
import org.hamcrest.CoreMatchers.notNullValue
import org.hamcrest.Matchers.equalTo
Expand Down Expand Up @@ -368,7 +370,7 @@ class LocationLayerControllerTest : EspressoTest() {
executeComponentTest(componentAction)

// Waiting for style to finish loading while pushing updates
onView(withId(R.id.content)).check(matches(isDisplayed()))
onView(withId(android.R.id.content)).check(matches(isDisplayed()))
}

@Test
Expand Down Expand Up @@ -399,7 +401,7 @@ class LocationLayerControllerTest : EspressoTest() {
executeComponentTest(componentAction)

// Waiting for style to finish loading while pushing updates
onView(withId(R.id.content)).check(matches(isDisplayed()))
onView(withId(android.R.id.content)).check(matches(isDisplayed()))
}

@Test
Expand Down Expand Up @@ -534,13 +536,21 @@ class LocationLayerControllerTest : EspressoTest() {
executeComponentTest(componentAction)
}

@Test
@UiThreadTest
fun test_15026_missingShadowGradientRadius() {
// test for https://github.com/mapbox/mapbox-gl-native/issues/15026
val shadowDrawable = BitmapUtils.getDrawableFromRes(context, R.drawable.mapbox_user_icon_shadow_0px_test)
Utils.generateShadow(shadowDrawable, 0f)
}

@After
override fun afterTest() {
super.afterTest()
IdlingRegistry.getInstance().unregister(styleChangeIdlingResource)
}

private fun executeComponentTest(listener: LocationComponentAction.OnPerformLocationComponentAction) {
onView(withId(R.id.content)).perform(LocationComponentAction(mapboxMap, listener))
onView(withId(android.R.id.content)).perform(LocationComponentAction(mapboxMap, listener))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<layer-list
xmlns:android="http://schemas.android.com/apk/res/android"
android:opacity="opaque">
<item
android:gravity="center">
<shape
android:shape="oval">
<size
android:width="22dp"
android:height="22dp"/>
<gradient
android:centerColor="#40000000"
android:endColor="#00000000"
android:gradientRadius="0px"
android:startColor="#40000000"
android:type="radial"/>
</shape>
</item>
</layer-list>

0 comments on commit afa7cea

Please sign in to comment.