diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index a56e9bed1a00235d96fc80b0300cf3707db9fe86..92130115f13e0db28a1227707fe0662bc87fe321 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -434,6 +434,7 @@ action("robolectric_tests") { "test/io/flutter/external/FlutterLaunchTests.java", "test/io/flutter/plugin/common/StandardMessageCodecTest.java", "test/io/flutter/plugin/editing/TextInputPluginTest.java", + "test/io/flutter/plugin/platform/PlatformPluginTest.java", "test/io/flutter/plugin/platform/SingleViewPresentationTest.java", "test/io/flutter/plugins/GeneratedPluginRegistrant.java", "test/io/flutter/util/PreconditionsTest.java", diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java index 15efc8127cdf2dbe869289c3280cd67661faf8f2..dd26ec65f32c7b86974cff18f4a48fa4edc85066 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java @@ -13,6 +13,7 @@ import android.graphics.Rect; import android.os.Build; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.view.HapticFeedbackConstants; import android.view.SoundEffectConstants; import android.view.View; @@ -121,7 +122,8 @@ public class PlatformPlugin { } } - private void vibrateHapticFeedback(PlatformChannel.HapticFeedbackType feedbackType) { + @VisibleForTesting + /* package */ void vibrateHapticFeedback(PlatformChannel.HapticFeedbackType feedbackType) { View view = activity.getWindow().getDecorView(); switch (feedbackType) { case STANDARD: @@ -134,11 +136,14 @@ public class PlatformPlugin { view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); break; case HEAVY_IMPACT: - // HapticFeedbackConstants.CONTEXT_CLICK from API level 23. - view.performHapticFeedback(6); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK); + } break; case SELECTION_CLICK: - view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + view.performHapticFeedback(HapticFeedbackConstants.CLOCK_TICK); + } break; } } @@ -171,7 +176,9 @@ public class PlatformPlugin { | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; - if (overlaysToShow.size() == 0) { + // The SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag was introduced in API 19, so we apply it + // if desired, and if the current Android version is 19 or greater. + if (overlaysToShow.size() == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; } diff --git a/shell/platform/android/test/io/flutter/FlutterTestSuite.java b/shell/platform/android/test/io/flutter/FlutterTestSuite.java index df54f4cf4f44b6a50b5b4a485e03d1df5cb0c42d..662cb5e160f99ffc54829965092b1fb86822f517 100644 --- a/shell/platform/android/test/io/flutter/FlutterTestSuite.java +++ b/shell/platform/android/test/io/flutter/FlutterTestSuite.java @@ -22,6 +22,7 @@ import io.flutter.embedding.engine.systemchannels.PlatformChannelTest; import io.flutter.external.FlutterLaunchTests; import io.flutter.plugin.common.StandardMessageCodecTest; import io.flutter.plugin.editing.TextInputPluginTest; +import io.flutter.plugin.platform.PlatformPluginTest; import io.flutter.plugin.platform.SingleViewPresentationTest; import io.flutter.util.PreconditionsTest; import test.io.flutter.embedding.engine.FlutterEngineTest; @@ -45,6 +46,7 @@ import test.io.flutter.embedding.engine.dart.DartExecutorTest; FlutterRendererTest.class, FlutterViewTest.class, PlatformChannelTest.class, + PlatformPluginTest.class, PluginComponentTest.class, PreconditionsTest.class, RenderingComponentTest.class, diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java new file mode 100644 index 0000000000000000000000000000000000000000..f1fb35e29dce055d810601c427dde63027e85047 --- /dev/null +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java @@ -0,0 +1,37 @@ +package io.flutter.plugin.platform; + +import android.app.Activity; +import android.view.View; +import android.view.Window; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; + +import io.flutter.embedding.engine.systemchannels.PlatformChannel; + +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +@Config(manifest=Config.NONE) +@RunWith(RobolectricTestRunner.class) +public class PlatformPluginTest { + @Config(sdk = 16) + @Test + public void itIgnoresNewHapticEventsOnOldAndroidPlatforms() { + View fakeDecorView = mock(View.class); + Window fakeWindow = mock(Window.class); + when(fakeWindow.getDecorView()).thenReturn(fakeDecorView); + Activity fakeActivity = mock(Activity.class); + when(fakeActivity.getWindow()).thenReturn(fakeWindow); + PlatformChannel fakePlatformChannel = mock(PlatformChannel.class); + PlatformPlugin platformPlugin = new PlatformPlugin(fakeActivity, fakePlatformChannel); + + // HEAVY_IMPACT haptic response is only available on "M" (23) and later. + platformPlugin.vibrateHapticFeedback(PlatformChannel.HapticFeedbackType.HEAVY_IMPACT); + + // SELECTION_CLICK haptic response is only available on "LOLLIPOP" (21) and later. + platformPlugin.vibrateHapticFeedback(PlatformChannel.HapticFeedbackType.SELECTION_CLICK); + } +}