diff --git a/ci/licenses_golden/licenses_flutter b/ci/licenses_golden/licenses_flutter index ae0f8eaab86b6..362dca00a8656 100644 --- a/ci/licenses_golden/licenses_flutter +++ b/ci/licenses_golden/licenses_flutter @@ -39011,6 +39011,7 @@ ORIGIN: ../../../flutter/shell/platform/android/image_external_texture_gl.h + .. ORIGIN: ../../../flutter/shell/platform/android/image_external_texture_vk.h + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/image_lru.cc + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/image_lru.h + ../../../flutter/LICENSE +ORIGIN: ../../../flutter/shell/platform/android/io/flutter/Build.java + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/io/flutter/BuildConfig.java + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/io/flutter/FlutterInjector.java + ../../../flutter/LICENSE ORIGIN: ../../../flutter/shell/platform/android/io/flutter/Log.java + ../../../flutter/LICENSE @@ -41869,6 +41870,7 @@ FILE: ../../../flutter/shell/platform/android/image_external_texture_vk.cc FILE: ../../../flutter/shell/platform/android/image_external_texture_vk.h FILE: ../../../flutter/shell/platform/android/image_lru.cc FILE: ../../../flutter/shell/platform/android/image_lru.h +FILE: ../../../flutter/shell/platform/android/io/flutter/Build.java FILE: ../../../flutter/shell/platform/android/io/flutter/BuildConfig.java FILE: ../../../flutter/shell/platform/android/io/flutter/FlutterInjector.java FILE: ../../../flutter/shell/platform/android/io/flutter/Log.java diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index 97eaf285ec2b3..69400de89e43f 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -194,6 +194,7 @@ embedding_sources_jar_filename = "$embedding_artifact_id-sources.jar" embedding_source_jar_path = "$root_out_dir/$embedding_sources_jar_filename" android_java_sources = [ + "io/flutter/Build.java", "io/flutter/FlutterInjector.java", "io/flutter/Log.java", "io/flutter/app/FlutterActivity.java", diff --git a/shell/platform/android/io/flutter/Build.java b/shell/platform/android/io/flutter/Build.java new file mode 100644 index 0000000000000..904bcc392d1c7 --- /dev/null +++ b/shell/platform/android/io/flutter/Build.java @@ -0,0 +1,27 @@ +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package io.flutter; + +/** A replacement of utilities from android.os.Build. */ +public class Build { + /** For use in place of the Android Build.VERSION_CODES class. */ + public static class API_LEVELS { + public static final int API_21 = 21; + public static final int API_22 = 22; + public static final int API_23 = 23; + public static final int API_24 = 24; + public static final int API_25 = 25; + public static final int API_26 = 26; + public static final int API_27 = 27; + public static final int API_28 = 28; + public static final int API_29 = 29; + public static final int API_30 = 30; + public static final int API_31 = 31; + public static final int API_32 = 32; + public static final int API_33 = 33; + public static final int API_34 = 34; + public static final int API_35 = 35; + } +} diff --git a/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java b/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java index 8ef7237a7a9e9..3e9c9fb8e0b60 100644 --- a/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java +++ b/shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java @@ -1,5 +1,7 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.content.Context; import android.graphics.Matrix; @@ -427,7 +429,7 @@ private void addPointerForIndex( } private float getHorizontalScrollFactor(@NonNull Context context) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { return ViewConfiguration.get(context).getScaledHorizontalScrollFactor(); } else { // Vertical scroll factor is not a typo. This is what View.java does in android. @@ -436,14 +438,14 @@ private float getHorizontalScrollFactor(@NonNull Context context) { } private float getVerticalScrollFactor(@NonNull Context context) { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { return getVerticalScrollFactorAbove26(context); } else { return getVerticalScrollFactorPre26(context); } } - @TargetApi(26) + @TargetApi(API_LEVELS.API_26) private float getVerticalScrollFactorAbove26(@NonNull Context context) { return ViewConfiguration.get(context).getScaledVerticalScrollFactor(); } diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java index 0135a9d4ec0d4..dcecd3fbc1bd2 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterActivity.java @@ -4,6 +4,7 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DART_ENTRYPOINT_META_DATA_KEY; import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DART_ENTRYPOINT_URI_META_DATA_KEY; import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.DEFAULT_BACKGROUND_MODE; @@ -654,7 +655,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { */ @VisibleForTesting public void registerOnBackInvokedCallback() { - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { getOnBackInvokedDispatcher() .registerOnBackInvokedCallback( OnBackInvokedDispatcher.PRIORITY_DEFAULT, onBackInvokedCallback); @@ -670,14 +671,14 @@ public void registerOnBackInvokedCallback() { */ @VisibleForTesting public void unregisterOnBackInvokedCallback() { - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { getOnBackInvokedDispatcher().unregisterOnBackInvokedCallback(onBackInvokedCallback); hasRegisteredBackCallback = false; } } private final OnBackInvokedCallback onBackInvokedCallback = - Build.VERSION.SDK_INT >= 33 + Build.VERSION.SDK_INT >= API_LEVELS.API_33 ? new OnBackInvokedCallback() { // TODO(garyq): Remove SuppressWarnings annotation. This was added to workaround // a google3 bug where the linter is not properly running against API 33, causing @@ -1369,7 +1370,7 @@ public void onFlutterUiDisplayed() { // * reportFullyDrawn behavior isn't tested on pre-Q versions. // See https://github.com/flutter/flutter/issues/46172, and // https://github.com/flutter/flutter/issues/88767. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_29) { reportFullyDrawn(); } } diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterImageView.java b/shell/platform/android/io/flutter/embedding/android/FlutterImageView.java index 9fd0f600ac3e4..df9d6b394dd7d 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterImageView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterImageView.java @@ -4,6 +4,8 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; @@ -109,7 +111,7 @@ private static ImageReader createImageReader(int width, int height) { logW("ImageReader height must be greater than 0, but given height=%d, set height=1", height); height = 1; } - if (android.os.Build.VERSION.SDK_INT >= 29) { + if (android.os.Build.VERSION.SDK_INT >= API_LEVELS.API_29) { return ImageReader.newInstance( width, height, @@ -251,9 +253,9 @@ private void closeCurrentImage() { } } - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) private void updateCurrentBitmap() { - if (android.os.Build.VERSION.SDK_INT >= 29) { + if (android.os.Build.VERSION.SDK_INT >= API_LEVELS.API_29) { final HardwareBuffer buffer = currentImage.getHardwareBuffer(); currentBitmap = Bitmap.wrapHardwareBuffer(buffer, ColorSpace.get(ColorSpace.Named.SRGB)); buffer.close(); diff --git a/shell/platform/android/io/flutter/embedding/android/FlutterView.java b/shell/platform/android/io/flutter/embedding/android/FlutterView.java index 1e576b9a21095..7272b5125ba05 100644 --- a/shell/platform/android/io/flutter/embedding/android/FlutterView.java +++ b/shell/platform/android/io/flutter/embedding/android/FlutterView.java @@ -4,6 +4,8 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; @@ -385,7 +387,7 @@ private void init() { // FlutterView needs to be focusable so that the InputMethodManager can interact with it. setFocusable(true); setFocusableInTouchMode(true); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { setImportantForAutofill(View.IMPORTANT_FOR_AUTOFILL_YES); } } @@ -532,7 +534,7 @@ protected void onDetachedFromWindow() { * Refresh {@link androidx.window.layout.WindowInfoTracker} and {@link android.view.DisplayCutout} * display features. Fold, hinge and cutout areas are populated here. */ - @TargetApi(28) + @TargetApi(API_LEVELS.API_28) protected void setWindowInfoListenerDisplayFeatures(WindowLayoutInfo layoutInfo) { List displayFeatures = layoutInfo.getDisplayFeatures(); List result = new ArrayList<>(); @@ -574,7 +576,7 @@ protected void setWindowInfoListenerDisplayFeatures(WindowLayoutInfo layoutInfo) // Data from the DisplayCutout bounds. Cutouts for cameras and other sensors are // populated here. DisplayCutout was introduced in API 28. - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { WindowInsets insets = getRootWindowInsets(); if (insets != null) { DisplayCutout cutout = insets.getDisplayCutout(); @@ -619,7 +621,7 @@ private ZeroSides calculateShouldZeroSides() { return ZeroSides.RIGHT; } else if (rotation == Surface.ROTATION_270) { // In android API >= 23, the nav bar always appears on the "bottom" (USB) side. - return Build.VERSION.SDK_INT >= 23 ? ZeroSides.LEFT : ZeroSides.RIGHT; + return Build.VERSION.SDK_INT >= API_LEVELS.API_23 ? ZeroSides.LEFT : ZeroSides.RIGHT; } // Ambiguous orientation due to landscape left/right default. Zero both sides. else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { @@ -677,7 +679,7 @@ public final WindowInsets onApplyWindowInsets(@NonNull WindowInsets insets) { WindowInsets newInsets = super.onApplyWindowInsets(insets); // getSystemGestureInsets() was introduced in API 29 and immediately deprecated in 30. - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT == API_LEVELS.API_29) { Insets systemGestureInsets = insets.getSystemGestureInsets(); viewportMetrics.systemGestureInsetTop = systemGestureInsets.top; viewportMetrics.systemGestureInsetRight = systemGestureInsets.right; @@ -689,7 +691,7 @@ public final WindowInsets onApplyWindowInsets(@NonNull WindowInsets insets) { boolean navigationBarVisible = (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) == 0; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) { int mask = 0; if (navigationBarVisible) { mask = mask | android.view.WindowInsets.Type.navigationBars(); @@ -956,7 +958,7 @@ public AccessibilityNodeProvider getAccessibilityNodeProvider() { @SuppressLint("SoonBlockedPrivateApi") @Nullable public View findViewByAccessibilityIdTraversal(int accessibilityId) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_29) { return findViewByAccessibilityIdRootedAtCurrentView(accessibilityId, this); } // Android Q or later doesn't call this method. @@ -1032,8 +1034,8 @@ private void resetWillNotDraw(boolean isAccessibilityEnabled, boolean isTouchExp // -------- Start: Mouse ------- @Override - @TargetApi(Build.VERSION_CODES.N) - @RequiresApi(Build.VERSION_CODES.N) + @TargetApi(API_LEVELS.API_24) + @RequiresApi(API_LEVELS.API_24) @NonNull public PointerIcon getSystemPointerIcon(int type) { return PointerIcon.getSystemIcon(getContext(), type); @@ -1098,7 +1100,7 @@ public void attachToFlutterEngine(@NonNull FlutterEngine flutterEngine) { // Initialize various components that know how to process Android View I/O // in a way that Flutter understands. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { mouseCursorPlugin = new MouseCursorPlugin(this, this.flutterEngine.getMouseCursorChannel()); } textInputPlugin = @@ -1412,7 +1414,7 @@ public void removeFlutterEngineAttachmentListener( boolean isNativeSpellCheckServiceDefined = false; if (textServicesManager != null) { - if (Build.VERSION.SDK_INT >= 31) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_31) { List enabledSpellCheckerInfos = textServicesManager.getEnabledSpellCheckerInfos(); boolean gboardSpellCheckerEnabled = diff --git a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java index db17bcc16b4d1..9a18c4ba57b40 100644 --- a/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java +++ b/shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java @@ -4,6 +4,8 @@ package io.flutter.embedding.engine; +import static io.flutter.Build.API_LEVELS; + import android.content.Context; import android.content.res.AssetManager; import android.graphics.Bitmap; @@ -566,7 +568,7 @@ public static native void nativeImageHeaderCallback( @VisibleForTesting @Nullable public static Bitmap decodeImage(@NonNull ByteBuffer buffer, long imageGeneratorAddress) { - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { ImageDecoder.Source source = ImageDecoder.createSource(buffer); try { return ImageDecoder.decodeBitmap( diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java index 7ee076e32f8ff..a4e1337b8f458 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java @@ -4,6 +4,8 @@ package io.flutter.embedding.engine.loader; +import static io.flutter.Build.API_LEVELS; + import android.app.ActivityManager; import android.content.Context; import android.content.pm.ApplicationInfo; @@ -203,7 +205,7 @@ public InitResult call() { } private static boolean areValidationLayersOnByDefault() { - if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (BuildConfig.DEBUG && Build.VERSION.SDK_INT >= API_LEVELS.API_26) { return Build.SUPPORTED_ABIS[0].equals("arm64-v8a"); } return false; diff --git a/shell/platform/android/io/flutter/embedding/engine/loader/ResourceExtractor.java b/shell/platform/android/io/flutter/embedding/engine/loader/ResourceExtractor.java index f71ac56df918b..13b153fff7800 100644 --- a/shell/platform/android/io/flutter/embedding/engine/loader/ResourceExtractor.java +++ b/shell/platform/android/io/flutter/embedding/engine/loader/ResourceExtractor.java @@ -4,6 +4,8 @@ package io.flutter.embedding.engine.loader; +import static io.flutter.Build.API_LEVELS; + import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.res.AssetManager; @@ -28,7 +30,7 @@ class ResourceExtractor { @SuppressWarnings("deprecation") static long getVersionCode(@NonNull PackageInfo packageInfo) { // Linter needs P (28) hardcoded or else it will fail these lines. - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { return packageInfo.getLongVersionCode(); } else { return packageInfo.versionCode; diff --git a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java index b58e92069bfb5..3f920cf126b34 100644 --- a/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java +++ b/shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java @@ -4,6 +4,8 @@ package io.flutter.embedding.engine.renderer; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.graphics.Bitmap; import android.graphics.ImageFormat; @@ -185,7 +187,7 @@ public SurfaceProducer createSurfaceProducer() { // version that is // running Vulkan, so we don't have to worry about it not being supported. final SurfaceProducer entry; - if (!debugForceSurfaceProducerGlTextures && Build.VERSION.SDK_INT >= 29) { + if (!debugForceSurfaceProducerGlTextures && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { final long id = nextTextureId.getAndIncrement(); final ImageReaderSurfaceProducer producer = new ImageReaderSurfaceProducer(id); registerImageTexture(id, producer); @@ -401,7 +403,7 @@ public void run() { // When we acquire the next image, close any ImageReaders that don't have any // more pending images. @Keep - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) final class ImageReaderSurfaceProducer implements TextureRegistry.SurfaceProducer, TextureRegistry.ImageConsumer, @@ -677,7 +679,7 @@ private void cleanup() { } } - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) private void waitOnFence(Image image) { try { SyncFence fence = image.getFence(); @@ -694,7 +696,7 @@ private void maybeWaitOnFence(Image image) { if (ignoringFence) { return; } - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { // The fence API is only available on Android >= 33. waitOnFence(image); return; @@ -770,7 +772,7 @@ public void scheduleFrame() { } @Override - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) public Image acquireLatestImage() { PerImage r = dequeueImage(); if (r == null) { @@ -810,7 +812,7 @@ protected void finalize() throws Throwable { } } - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) private ImageReader createImageReader33() { final ImageReader.Builder builder = new ImageReader.Builder(requestedWidth, requestedHeight); // Allow for double buffering. @@ -828,7 +830,7 @@ private ImageReader createImageReader33() { return reader; } - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) private ImageReader createImageReader29() { final ImageReader reader = ImageReader.newInstance( @@ -841,9 +843,9 @@ private ImageReader createImageReader29() { } private ImageReader createImageReader() { - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { return createImageReader33(); - } else if (Build.VERSION.SDK_INT >= 29) { + } else if (Build.VERSION.SDK_INT >= API_LEVELS.API_29) { return createImageReader29(); } throw new UnsupportedOperationException( @@ -926,7 +928,7 @@ public void pushImage(Image image) { } } - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) private void waitOnFence(Image image) { try { SyncFence fence = image.getFence(); @@ -936,7 +938,7 @@ private void waitOnFence(Image image) { } } - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) private void maybeWaitOnFence(Image image) { if (image == null) { return; @@ -944,7 +946,7 @@ private void maybeWaitOnFence(Image image) { if (ignoringFence) { return; } - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { // The fence API is only available on Android >= 33. waitOnFence(image); return; @@ -955,7 +957,7 @@ private void maybeWaitOnFence(Image image) { } @Override - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) public Image acquireLatestImage() { Image r; synchronized (this) { diff --git a/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java b/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java index bdd7f0cba003d..ec0dc28315f41 100644 --- a/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java +++ b/shell/platform/android/io/flutter/embedding/engine/systemchannels/SettingsChannel.java @@ -1,5 +1,7 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.os.Build; import android.util.DisplayMetrics; @@ -37,7 +39,7 @@ public SettingsChannel(@NonNull DartExecutor dartExecutor) { @SuppressLint("AnnotateVersionCheck") public static boolean hasNonlinearTextScalingSupport() { - return Build.VERSION.SDK_INT >= 34; + return Build.VERSION.SDK_INT >= API_LEVELS.API_34; } // This method will only be called on Flutter's UI thread. diff --git a/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java b/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java index e0f95681f3b9c..2c3cf3307b863 100644 --- a/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java +++ b/shell/platform/android/io/flutter/embedding/engine/systemchannels/TextInputChannel.java @@ -1,5 +1,7 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; + import android.os.Build; import android.os.Bundle; import android.view.View; @@ -542,7 +544,7 @@ public static Autofill fromJson(@NonNull JSONObject json) @NonNull private static String translateAutofillHint(@NonNull String hint) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return hint; } switch (hint) { diff --git a/shell/platform/android/io/flutter/plugin/editing/ImeSyncDeferringInsetsCallback.java b/shell/platform/android/io/flutter/plugin/editing/ImeSyncDeferringInsetsCallback.java index 830d7aace0340..9aec85d1e1e5e 100644 --- a/shell/platform/android/io/flutter/plugin/editing/ImeSyncDeferringInsetsCallback.java +++ b/shell/platform/android/io/flutter/plugin/editing/ImeSyncDeferringInsetsCallback.java @@ -4,6 +4,8 @@ package io.flutter.plugin.editing; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.graphics.Insets; @@ -42,8 +44,8 @@ // dispatched again, this time avoiding any flicker since the animation is now // complete. @VisibleForTesting -@TargetApi(30) -@RequiresApi(30) +@TargetApi(API_LEVELS.API_30) +@RequiresApi(API_LEVELS.API_30) @SuppressLint({"NewApi", "Override"}) @Keep class ImeSyncDeferringInsetsCallback { diff --git a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java index 3f868e74b44c8..1f688d7beb281 100644 --- a/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java +++ b/shell/platform/android/io/flutter/plugin/editing/InputConnectionAdaptor.java @@ -4,6 +4,8 @@ package io.flutter.plugin.editing; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.content.ClipData; import android.content.ClipboardManager; @@ -476,11 +478,11 @@ public boolean performEditorAction(int actionCode) { } @Override - @TargetApi(25) - @RequiresApi(25) + @TargetApi(API_LEVELS.API_25) + @RequiresApi(API_LEVELS.API_25) public boolean commitContent(InputContentInfo inputContentInfo, int flags, Bundle opts) { // Ensure permission is granted. - if (Build.VERSION.SDK_INT >= 25 + if (Build.VERSION.SDK_INT >= API_LEVELS.API_25 && (flags & InputConnectionCompat.INPUT_CONTENT_GRANT_READ_URI_PERMISSION) != 0) { try { inputContentInfo.requestPermission(); diff --git a/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java b/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java index 91644f3514b81..d6c3c6f90d483 100644 --- a/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java +++ b/shell/platform/android/io/flutter/plugin/editing/TextInputPlugin.java @@ -4,6 +4,8 @@ package io.flutter.plugin.editing; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Rect; @@ -69,7 +71,7 @@ public TextInputPlugin( // Create a default object. mEditable = new ListenableEditingState(null, mView); mImm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { afm = view.getContext().getSystemService(AutofillManager.class); } else { afm = null; @@ -78,7 +80,7 @@ public TextInputPlugin( // Sets up syncing ime insets with the framework, allowing // the Flutter view to grow and shrink to accommodate Android // controlled keyboard animations. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) { imeSyncCallback = new ImeSyncDeferringInsetsCallback(view); imeSyncCallback.install(); } @@ -107,7 +109,7 @@ public void requestAutofill() { @Override public void finishAutofillContext(boolean shouldSave) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || afm == null) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26 || afm == null) { return; } if (shouldSave) { @@ -312,7 +314,7 @@ public InputConnection createInputConnection( configuration.textCapitalization); outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26 && !configuration.enableIMEPersonalizedLearning) { outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_PERSONALIZED_LEARNING; } @@ -676,7 +678,7 @@ private boolean needsAutofill() { } private void notifyViewEntered() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || afm == null || !needsAutofill()) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26 || afm == null || !needsAutofill()) { return; } @@ -689,7 +691,7 @@ private void notifyViewEntered() { } private void notifyViewExited() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O + if (Build.VERSION.SDK_INT < API_LEVELS.API_26 || afm == null || configuration == null || configuration.autofill == null @@ -702,7 +704,7 @@ private void notifyViewExited() { } private void notifyValueChanged(String newValue) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || afm == null || !needsAutofill()) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26 || afm == null || !needsAutofill()) { return; } @@ -711,7 +713,7 @@ private void notifyValueChanged(String newValue) { } private void updateAutofillConfigurationIfNeeded(TextInputChannel.Configuration configuration) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } @@ -741,7 +743,7 @@ private void updateAutofillConfigurationIfNeeded(TextInputChannel.Configuration } public void onProvideAutofillVirtualStructure(@NonNull ViewStructure structure, int flags) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O || !needsAutofill()) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26 || !needsAutofill()) { return; } @@ -789,7 +791,7 @@ public void onProvideAutofillVirtualStructure(@NonNull ViewStructure structure, } public void autofill(@NonNull SparseArray values) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } diff --git a/shell/platform/android/io/flutter/plugin/localization/LocalizationPlugin.java b/shell/platform/android/io/flutter/plugin/localization/LocalizationPlugin.java index 0998ee74f48a4..1b5d398a98231 100644 --- a/shell/platform/android/io/flutter/plugin/localization/LocalizationPlugin.java +++ b/shell/platform/android/io/flutter/plugin/localization/LocalizationPlugin.java @@ -4,6 +4,8 @@ package io.flutter.plugin.localization; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; @@ -79,7 +81,7 @@ public Locale resolveNativeLocale(@Nullable List supportedLocales) { // // LanguageRange and Locale.lookup was added in API 26 and is the preferred way to // select a locale. Pre-API 26, we implement a manual locale resolution. - if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { // Modern locale resolution using LanguageRange // https://developer.android.com/guide/topics/resources/multilingual-support#postN List languageRanges = new ArrayList<>(); @@ -104,7 +106,7 @@ public Locale resolveNativeLocale(@Nullable List supportedLocales) { return platformResolvedLocale; } return supportedLocales.get(0); - } else if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + } else if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { // Modern locale resolution without languageRange // https://developer.android.com/guide/topics/resources/multilingual-support#postN LocaleList localeList = context.getResources().getConfiguration().getLocales(); @@ -160,7 +162,7 @@ public Locale resolveNativeLocale(@Nullable List supportedLocales) { @SuppressWarnings("deprecation") public void sendLocalesToFlutter(@NonNull Configuration config) { List locales = new ArrayList<>(); - if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { LocaleList localeList = config.getLocales(); int localeCount = localeList.size(); for (int index = 0; index < localeCount; ++index) { diff --git a/shell/platform/android/io/flutter/plugin/mouse/MouseCursorPlugin.java b/shell/platform/android/io/flutter/plugin/mouse/MouseCursorPlugin.java index f9c3a8e6f76f9..e6a4f7083bfe1 100644 --- a/shell/platform/android/io/flutter/plugin/mouse/MouseCursorPlugin.java +++ b/shell/platform/android/io/flutter/plugin/mouse/MouseCursorPlugin.java @@ -4,8 +4,9 @@ package io.flutter.plugin.mouse; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; -import android.os.Build; import android.view.PointerIcon; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; @@ -13,8 +14,8 @@ import java.util.HashMap; /** A mandatory plugin that handles mouse cursor requests. */ -@TargetApi(Build.VERSION_CODES.N) -@RequiresApi(Build.VERSION_CODES.N) +@TargetApi(API_LEVELS.API_24) +@RequiresApi(API_LEVELS.API_24) public class MouseCursorPlugin { @NonNull private final MouseCursorViewDelegate mView; @NonNull private final MouseCursorChannel mouseCursorChannel; diff --git a/shell/platform/android/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTarget.java b/shell/platform/android/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTarget.java index 9a89d545072ea..4cf0cd01ed9b3 100644 --- a/shell/platform/android/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTarget.java +++ b/shell/platform/android/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTarget.java @@ -1,5 +1,7 @@ package io.flutter.plugin.platform; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.graphics.ImageFormat; import android.hardware.HardwareBuffer; @@ -11,7 +13,7 @@ import io.flutter.Log; import io.flutter.view.TextureRegistry.ImageTextureEntry; -@TargetApi(29) +@TargetApi(API_LEVELS.API_29) public class ImageReaderPlatformViewRenderTarget implements PlatformViewRenderTarget { private ImageTextureEntry textureEntry; private ImageReader reader; @@ -48,7 +50,7 @@ public void onImageAvailable(ImageReader reader) { } }; - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) protected ImageReader createImageReader33() { final ImageReader.Builder builder = new ImageReader.Builder(bufferWidth, bufferHeight); // Allow for double buffering. @@ -67,7 +69,7 @@ protected ImageReader createImageReader33() { return reader; } - @TargetApi(29) + @TargetApi(API_LEVELS.API_29) protected ImageReader createImageReader29() { final ImageReader reader = ImageReader.newInstance( @@ -81,9 +83,9 @@ protected ImageReader createImageReader29() { } protected ImageReader createImageReader() { - if (Build.VERSION.SDK_INT >= 33) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { return createImageReader33(); - } else if (Build.VERSION.SDK_INT >= 29) { + } else if (Build.VERSION.SDK_INT >= API_LEVELS.API_29) { return createImageReader29(); } throw new UnsupportedOperationException( @@ -91,7 +93,7 @@ protected ImageReader createImageReader() { } public ImageReaderPlatformViewRenderTarget(ImageTextureEntry textureEntry) { - if (Build.VERSION.SDK_INT < 29) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_29) { throw new UnsupportedOperationException( "ImageReaderPlatformViewRenderTarget requires API version 29+"); } diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java index d3926440fac43..9810623f8560b 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java @@ -4,6 +4,8 @@ package io.flutter.plugin.platform; +import static io.flutter.Build.API_LEVELS; + import android.app.Activity; import android.app.ActivityManager.TaskDescription; import android.content.ClipData; @@ -200,7 +202,7 @@ private void playSystemSound(@NonNull PlatformChannel.SoundType soundType) { view.performHapticFeedback(HapticFeedbackConstants.KEYBOARD_TAP); break; case HEAVY_IMPACT: - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_23) { view.performHapticFeedback(HapticFeedbackConstants.CONTEXT_CLICK); } break; @@ -217,7 +219,7 @@ private void setSystemChromePreferredOrientations(int androidOrientation) { @SuppressWarnings("deprecation") private void setSystemChromeApplicationSwitcherDescription( PlatformChannel.AppSwitcherDescription description) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_28) { activity.setTaskDescription( new TaskDescription(description.label, /* icon= */ null, description.color)); } else { @@ -308,7 +310,7 @@ private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode sys | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; } else if (systemUiMode == PlatformChannel.SystemUiMode.EDGE_TO_EDGE - && Build.VERSION.SDK_INT >= 29) { + && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { // EDGE TO EDGE // Available starting at 29 // SDK 29 and up will apply a translucent body scrim behind 2/3 button navigation bars @@ -386,7 +388,7 @@ private void setSystemChromeSystemUIOverlayStyle( WindowInsetsControllerCompat windowInsetsControllerCompat = new WindowInsetsControllerCompat(window, view); - if (Build.VERSION.SDK_INT < 30) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_30) { // Flag set to specify that this window is responsible for drawing the background for the // system bars. Must be set for all operations on API < 30 excluding enforcing system // bar contrasts. Deprecated in API 30. @@ -407,7 +409,7 @@ private void setSystemChromeSystemUIOverlayStyle( // If transparent, SDK 29 and higher may apply a translucent scrim behind the bar to ensure // proper contrast. This can be overridden with // SystemChromeStyle.systemStatusBarContrastEnforced. - if (Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_23) { if (systemChromeStyle.statusBarIconBrightness != null) { switch (systemChromeStyle.statusBarIconBrightness) { case DARK: @@ -430,7 +432,8 @@ private void setSystemChromeSystemUIOverlayStyle( // You can't override the enforced contrast for a transparent status bar until SDK 29. // This overrides the translucent scrim that may be placed behind the bar on SDK 29+ to ensure // contrast is appropriate when using full screen layout modes like Edge to Edge. - if (systemChromeStyle.systemStatusBarContrastEnforced != null && Build.VERSION.SDK_INT >= 29) { + if (systemChromeStyle.systemStatusBarContrastEnforced != null + && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { window.setStatusBarContrastEnforced(systemChromeStyle.systemStatusBarContrastEnforced); } @@ -441,7 +444,7 @@ private void setSystemChromeSystemUIOverlayStyle( // If transparent, SDK 29 and higher may apply a translucent scrim behind 2/3 button navigation // bars to ensure proper contrast. This can be overridden with // SystemChromeStyle.systemNavigationBarContrastEnforced. - if (Build.VERSION.SDK_INT >= 26) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { if (systemChromeStyle.systemNavigationBarIconBrightness != null) { switch (systemChromeStyle.systemNavigationBarIconBrightness) { case DARK: @@ -462,7 +465,8 @@ private void setSystemChromeSystemUIOverlayStyle( } } // You can't change the color of the navigation bar divider color until SDK 28. - if (systemChromeStyle.systemNavigationBarDividerColor != null && Build.VERSION.SDK_INT >= 28) { + if (systemChromeStyle.systemNavigationBarDividerColor != null + && Build.VERSION.SDK_INT >= API_LEVELS.API_28) { window.setNavigationBarDividerColor(systemChromeStyle.systemNavigationBarDividerColor); } @@ -471,7 +475,7 @@ private void setSystemChromeSystemUIOverlayStyle( // SDK 29+ to ensure contrast is appropriate when using full screen layout modes like // Edge to Edge. if (systemChromeStyle.systemNavigationBarContrastEnforced != null - && Build.VERSION.SDK_INT >= 29) { + && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { window.setNavigationBarContrastEnforced( systemChromeStyle.systemNavigationBarContrastEnforced); } diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java index 9fac8a553eb8b..f1e91a99aaf52 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewWrapper.java @@ -4,6 +4,8 @@ package io.flutter.plugin.platform; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.content.Context; @@ -37,7 +39,7 @@ *

Since the view is in the Android view hierarchy, keyboard and accessibility interactions * behave normally. */ -@TargetApi(23) +@TargetApi(API_LEVELS.API_23) public class PlatformViewWrapper extends FrameLayout { private static final String TAG = "PlatformViewWrapper"; diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index e04e5679d5df6..6e2b2ab250f82 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -6,6 +6,7 @@ import static android.view.MotionEvent.PointerCoords; import static android.view.MotionEvent.PointerProperties; +import static io.flutter.Build.API_LEVELS; import android.annotation.TargetApi; import android.content.Context; @@ -210,7 +211,7 @@ public long createForTextureLayer( // view hierarchy via callbacks such as ViewParent#onDescendantInvalidated(). // - The API level is <23, due to TLHC implementation API requirements. final boolean supportsTextureLayerMode = - Build.VERSION.SDK_INT >= 23 + Build.VERSION.SDK_INT >= API_LEVELS.API_23 && !ViewUtils.hasChildViewOfType( embeddedView, VIEW_TYPES_REQUIRE_VIRTUAL_DISPLAY); @@ -593,7 +594,7 @@ private long configureForVirtualDisplay( // Configures the view for Texture Layer Hybrid Composition mode, returning the associated // texture ID. - @TargetApi(23) + @TargetApi(API_LEVELS.API_23) @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) public long configureForTextureLayerComposition( @NonNull PlatformView platformView, @@ -964,12 +965,12 @@ private void unlockInputConnection(@NonNull VirtualDisplayController controller) private static PlatformViewRenderTarget makePlatformViewRenderTarget( TextureRegistry textureRegistry) { - if (enableSurfaceProducerRenderTarget && Build.VERSION.SDK_INT >= 29) { + if (enableSurfaceProducerRenderTarget && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { final TextureRegistry.SurfaceProducer textureEntry = textureRegistry.createSurfaceProducer(); Log.i(TAG, "PlatformView is using SurfaceProducer backend"); return new SurfaceProducerPlatformViewRenderTarget(textureEntry); } - if (enableImageRenderTarget && Build.VERSION.SDK_INT >= 29) { + if (enableImageRenderTarget && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { final TextureRegistry.ImageTextureEntry textureEntry = textureRegistry.createImageTexture(); Log.i(TAG, "PlatformView is using ImageReader backend"); return new ImageReaderPlatformViewRenderTarget(textureEntry); diff --git a/shell/platform/android/io/flutter/plugin/platform/SingleViewWindowManager.java b/shell/platform/android/io/flutter/plugin/platform/SingleViewWindowManager.java index ad004acbf4cad..ffeb3871afc47 100644 --- a/shell/platform/android/io/flutter/plugin/platform/SingleViewWindowManager.java +++ b/shell/platform/android/io/flutter/plugin/platform/SingleViewWindowManager.java @@ -4,7 +4,8 @@ package io.flutter.plugin.platform; -import android.os.Build; +import static io.flutter.Build.API_LEVELS; + import android.view.Display; import android.view.View; import android.view.ViewGroup; @@ -86,40 +87,40 @@ public void removeView(View view) { fakeWindowRootView.removeView(view); } - @RequiresApi(api = Build.VERSION_CODES.R) + @RequiresApi(api = API_LEVELS.API_30) @NonNull @Override public WindowMetrics getCurrentWindowMetrics() { return delegate.getCurrentWindowMetrics(); } - @RequiresApi(api = Build.VERSION_CODES.R) + @RequiresApi(api = API_LEVELS.API_30) @NonNull @Override public WindowMetrics getMaximumWindowMetrics() { return delegate.getMaximumWindowMetrics(); } - @RequiresApi(api = Build.VERSION_CODES.S) + @RequiresApi(api = API_LEVELS.API_31) @Override public boolean isCrossWindowBlurEnabled() { return delegate.isCrossWindowBlurEnabled(); } - @RequiresApi(api = Build.VERSION_CODES.S) + @RequiresApi(api = API_LEVELS.API_31) @Override public void addCrossWindowBlurEnabledListener(@NonNull Consumer listener) { delegate.addCrossWindowBlurEnabledListener(listener); } - @RequiresApi(api = Build.VERSION_CODES.S) + @RequiresApi(api = API_LEVELS.API_31) @Override public void addCrossWindowBlurEnabledListener( @NonNull Executor executor, @NonNull Consumer listener) { delegate.addCrossWindowBlurEnabledListener(executor, listener); } - @RequiresApi(api = Build.VERSION_CODES.S) + @RequiresApi(api = API_LEVELS.API_31) @Override public void removeCrossWindowBlurEnabledListener(@NonNull Consumer listener) { delegate.removeCrossWindowBlurEnabledListener(listener); diff --git a/shell/platform/android/io/flutter/plugin/platform/SurfaceProducerPlatformViewRenderTarget.java b/shell/platform/android/io/flutter/plugin/platform/SurfaceProducerPlatformViewRenderTarget.java index b37b53f1561c3..03e28d28806f4 100644 --- a/shell/platform/android/io/flutter/plugin/platform/SurfaceProducerPlatformViewRenderTarget.java +++ b/shell/platform/android/io/flutter/plugin/platform/SurfaceProducerPlatformViewRenderTarget.java @@ -1,10 +1,12 @@ package io.flutter.plugin.platform; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.view.Surface; import io.flutter.view.TextureRegistry.SurfaceProducer; -@TargetApi(29) +@TargetApi(API_LEVELS.API_29) public class SurfaceProducerPlatformViewRenderTarget implements PlatformViewRenderTarget { private static final String TAG = "SurfaceProducerRenderTarget"; private SurfaceProducer producer; diff --git a/shell/platform/android/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java b/shell/platform/android/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java index f629daa26c425..4f1bdd62b4e55 100644 --- a/shell/platform/android/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java +++ b/shell/platform/android/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTarget.java @@ -1,6 +1,7 @@ package io.flutter.plugin.platform; import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE; +import static io.flutter.Build.API_LEVELS; import android.annotation.TargetApi; import android.graphics.SurfaceTexture; @@ -9,7 +10,7 @@ import io.flutter.view.TextureRegistry; import io.flutter.view.TextureRegistry.SurfaceTextureEntry; -@TargetApi(26) +@TargetApi(API_LEVELS.API_26) public class SurfaceTexturePlatformViewRenderTarget implements PlatformViewRenderTarget { private static final String TAG = "SurfaceTexturePlatformViewRenderTarget"; @@ -32,7 +33,7 @@ public void onTrimMemory(int level) { // See https://github.com/flutter/flutter/issues/103870 for more details. // // Here our workaround is to recreate the surface before using it. - if (level == TRIM_MEMORY_COMPLETE && Build.VERSION.SDK_INT >= 29) { + if (level == TRIM_MEMORY_COMPLETE && Build.VERSION.SDK_INT >= API_LEVELS.API_29) { shouldRecreateSurfaceForLowMemory = true; } } @@ -57,7 +58,7 @@ protected Surface createSurface() { /** Implementation of PlatformViewRenderTarget */ public SurfaceTexturePlatformViewRenderTarget(SurfaceTextureEntry surfaceTextureEntry) { - if (Build.VERSION.SDK_INT < 23) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_23) { throw new UnsupportedOperationException( "Platform views cannot be displayed below API level 23" + "You can prevent this issue by setting `minSdkVersion: 23` in build.gradle."); diff --git a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java index 44389b9044fab..5de42299e00c4 100644 --- a/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java +++ b/shell/platform/android/io/flutter/plugin/platform/VirtualDisplayController.java @@ -5,6 +5,7 @@ package io.flutter.plugin.platform; import static android.view.View.OnFocusChangeListener; +import static io.flutter.Build.API_LEVELS; import android.annotation.TargetApi; import android.content.Context; @@ -147,7 +148,7 @@ public void resize(final int width, final int height, final Runnable onNewSizeFr getView().postDelayed(onNewSizeFrameAvailable, 0); return; } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_31) { resize31(getView(), width, height, onNewSizeFrameAvailable); return; } @@ -231,7 +232,7 @@ public void dispose() { } // On Android versions 31+ resizing of a Virtual Display's Presentation is natively supported. - @TargetApi(31) + @TargetApi(API_LEVELS.API_31) private void resize31( View embeddedView, int width, int height, final Runnable onNewSizeFrameAvailable) { renderTarget.resize(width, height); diff --git a/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java b/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java index 3338ed2cd9bcf..ba56ff4007688 100644 --- a/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java +++ b/shell/platform/android/io/flutter/plugin/text/ProcessTextPlugin.java @@ -4,6 +4,8 @@ package io.flutter.plugin.text; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.app.Activity; import android.content.Intent; @@ -70,7 +72,7 @@ public void processTextAction( return; } - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_23) { result.error("error", "Android version not supported", null); return; } @@ -105,14 +107,14 @@ public void processTextAction( private void cacheResolveInfos() { resolveInfosById = new HashMap(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_23) { return; } Intent intent = new Intent().setAction(Intent.ACTION_PROCESS_TEXT).setType("text/plain"); List infos; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_33) { infos = packageManager.queryIntentActivities(intent, PackageManager.ResolveInfoFlags.of(0)); } else { infos = packageManager.queryIntentActivities(intent, 0); @@ -134,8 +136,8 @@ private void cacheResolveInfos() { *

When an activity does not return a value. the request is completed successfully and returns * null. */ - @TargetApi(Build.VERSION_CODES.M) - @RequiresApi(Build.VERSION_CODES.M) + @TargetApi(API_LEVELS.API_23) + @RequiresApi(API_LEVELS.API_23) public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent intent) { // Return early if the result is not related to a request sent by this plugin. if (!requestsByCode.containsKey(requestCode)) { diff --git a/shell/platform/android/io/flutter/util/HandlerCompat.java b/shell/platform/android/io/flutter/util/HandlerCompat.java index de391419a9abd..39a7f7d6ff610 100644 --- a/shell/platform/android/io/flutter/util/HandlerCompat.java +++ b/shell/platform/android/io/flutter/util/HandlerCompat.java @@ -4,6 +4,8 @@ package io.flutter.util; +import static io.flutter.Build.API_LEVELS; + import android.os.Build; import android.os.Handler; import android.os.Looper; @@ -27,7 +29,7 @@ public final class HandlerCompat { * @see Handler#createAsync(Looper) */ public static Handler createAsyncHandler(Looper looper) { - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { return Handler.createAsync(looper); } return new Handler(looper); diff --git a/shell/platform/android/io/flutter/util/PathUtils.java b/shell/platform/android/io/flutter/util/PathUtils.java index 2427a6285b21c..15b6d1e752849 100644 --- a/shell/platform/android/io/flutter/util/PathUtils.java +++ b/shell/platform/android/io/flutter/util/PathUtils.java @@ -4,6 +4,8 @@ package io.flutter.util; +import static io.flutter.Build.API_LEVELS; + import android.content.Context; import android.os.Build; import androidx.annotation.NonNull; @@ -48,7 +50,7 @@ public static String getCacheDirectory(@NonNull Context applicationContext) { } private static String getDataDirPath(Context applicationContext) { - if (Build.VERSION.SDK_INT >= 24) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { return applicationContext.getDataDir().getPath(); } else { return applicationContext.getApplicationInfo().dataDir; diff --git a/shell/platform/android/io/flutter/view/AccessibilityBridge.java b/shell/platform/android/io/flutter/view/AccessibilityBridge.java index 4536897225a23..a0280322c06f9 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityBridge.java +++ b/shell/platform/android/io/flutter/view/AccessibilityBridge.java @@ -4,6 +4,8 @@ package io.flutter.view; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; @@ -324,7 +326,7 @@ public void onTooltip(@NonNull String message) { // // To reproduce native behavior, see // https://developer.android.com/guide/topics/ui/tooltips. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { return; } AccessibilityEvent e = @@ -478,7 +480,7 @@ public void onTouchExplorationStateChanged(boolean isTouchExplorationEnabled) { // Tells Flutter whether the text should be bolded or not. If the user changes bold text // setting, the configuration will change and trigger a re-build of the accesibiltyBridge. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_31) { setBoldTextFlag(); } @@ -543,8 +545,8 @@ private boolean shouldSetCollectionInfo(final SemanticsNode semanticsNode) { accessibilityFocusedSemanticsNode, o -> o.hasFlag(Flag.HAS_IMPLICIT_SCROLLING))); } - @TargetApi(31) - @RequiresApi(31) + @TargetApi(API_LEVELS.API_31) + @RequiresApi(API_LEVELS.API_31) private void setBoldTextFlag() { if (rootAccessibilityView == null || rootAccessibilityView.getResources() == null) { return; @@ -616,7 +618,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { if (flutterSemanticsTree.containsKey(ROOT_NODE_ID)) { result.addChild(rootAccessibilityView, ROOT_NODE_ID); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { result.setImportantForAccessibility(false); } return result; @@ -652,7 +654,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { // Accessibility Scanner uses isImportantForAccessibility to decide whether to check // or skip this node. - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { result.setImportantForAccessibility(isImportant(semanticsNode)); } @@ -763,7 +765,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { result.setParent(rootAccessibilityView); } - if (semanticsNode.previousNodeId != -1 && Build.VERSION.SDK_INT >= 22) { + if (semanticsNode.previousNodeId != -1 && Build.VERSION.SDK_INT >= API_LEVELS.API_22) { result.setTraversalAfter(rootAccessibilityView, semanticsNode.previousNodeId); } @@ -881,12 +883,12 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { // for non-scopes-routes semantics nodes. if (semanticsNode.hasFlag(Flag.IS_TEXT_FIELD)) { result.setText(semanticsNode.getValue()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { result.setHintText(semanticsNode.getTextFieldHint()); } } else if (!semanticsNode.hasFlag(Flag.SCOPES_ROUTE)) { CharSequence content = semanticsNode.getValueLabelHint(); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_28) { if (semanticsNode.tooltip != null) { // For backward compatibility with Flutter SDK before Android API // level 28, the tooltip is appended at the end of content description. @@ -899,7 +901,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { } } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { if (semanticsNode.tooltip != null) { result.setTooltipText(semanticsNode.tooltip); } @@ -925,7 +927,7 @@ public AccessibilityNodeInfo createAccessibilityNodeInfo(int virtualViewId) { result.setSelected(semanticsNode.hasFlag(Flag.IS_SELECTED)); // Heading support - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { result.setHeading(semanticsNode.hasFlag(Flag.IS_HEADER)); } @@ -1623,13 +1625,13 @@ void updateSemantics( // In Android devices API 23 and above, the system nav bar can be placed on the left side // of the screen in landscape mode. We must handle the translation ourselves for the // a11y nodes. - if (Build.VERSION.SDK_INT >= 23) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_23) { boolean needsToApplyLeftCutoutInset = true; // In Android devices API 28 and above, the `layoutInDisplayCutoutMode` window attribute // can be set to allow overlapping content within the cutout area. Query the attribute // to figure out whether the content overlaps with the cutout and decide whether to // apply cutout inset. - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { needsToApplyLeftCutoutInset = doesLayoutInDisplayCutoutModeRequireLeftInset(); } @@ -1911,7 +1913,7 @@ private void onWindowNameChange(@NonNull SemanticsNode route) { // next. routeName = " "; } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { setAccessibilityPaneTitle(routeName); } else { AccessibilityEvent event = @@ -1921,8 +1923,8 @@ private void onWindowNameChange(@NonNull SemanticsNode route) { } } - @TargetApi(28) - @RequiresApi(28) + @TargetApi(API_LEVELS.API_28) + @RequiresApi(API_LEVELS.API_28) private void setAccessibilityPaneTitle(String title) { rootAccessibilityView.setAccessibilityPaneTitle(title); } @@ -1970,8 +1972,8 @@ public AccessibilityEvent obtainAccessibilityEvent(int eventType) { * *

The {@code layoutInDisplayCutoutMode} is added after API level 28. */ - @TargetApi(28) - @RequiresApi(28) + @TargetApi(API_LEVELS.API_28) + @RequiresApi(API_LEVELS.API_28) private boolean doesLayoutInDisplayCutoutModeRequireLeftInset() { Context context = rootAccessibilityView.getContext(); Activity activity = ViewUtils.getActivity(context); diff --git a/shell/platform/android/io/flutter/view/AccessibilityViewEmbedder.java b/shell/platform/android/io/flutter/view/AccessibilityViewEmbedder.java index 09fecf5e9dd10..7260d4a8681a5 100644 --- a/shell/platform/android/io/flutter/view/AccessibilityViewEmbedder.java +++ b/shell/platform/android/io/flutter/view/AccessibilityViewEmbedder.java @@ -4,6 +4,8 @@ package io.flutter.view; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.graphics.Rect; import android.os.Build; @@ -242,16 +244,16 @@ private void copyAccessibilityFields( output.setRangeInfo(input.getRangeInfo()); output.setError(input.getError()); output.setMaxTextLength(input.getMaxTextLength()); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_23) { output.setContextClickable(input.isContextClickable()); // TODO(amirh): copy traversal before and after. // https://github.com/flutter/flutter/issues/29718 } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { output.setDrawingOrder(input.getDrawingOrder()); output.setImportantForAccessibility(input.isImportantForAccessibility()); } - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_26) { output.setAvailableExtraData(input.getAvailableExtraData()); output.setHintText(input.getHintText()); output.setShowingHintText(input.isShowingHintText()); @@ -447,7 +449,7 @@ private ReflectionAccessors() { Log.w(TAG, "can't invoke AccessibiiltyRecord#getSourceNodeId with reflection"); } // Reflection access is not allowed starting Android P on these methods. - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT <= API_LEVELS.API_26) { try { getParentNodeId = AccessibilityNodeInfo.class.getMethod("getParentNodeId"); } catch (NoSuchMethodException e) { @@ -565,7 +567,7 @@ private Long getParentNodeId(@NonNull AccessibilityNodeInfo node) { // details change from our assumptions in this method, this will silently break. @Nullable private static Long yoinkParentIdFromParcel(AccessibilityNodeInfo node) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { Log.w(TAG, "Unexpected Android version. Unable to find the parent ID."); return null; } diff --git a/shell/platform/android/io/flutter/view/FlutterView.java b/shell/platform/android/io/flutter/view/FlutterView.java index dde0422c6a10a..73794cd46e41f 100644 --- a/shell/platform/android/io/flutter/view/FlutterView.java +++ b/shell/platform/android/io/flutter/view/FlutterView.java @@ -4,6 +4,8 @@ package io.flutter.view; +import static io.flutter.Build.API_LEVELS; + import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.Activity; @@ -234,7 +236,7 @@ public void onPostResume() { new TextInputPlugin(this, new TextInputChannel(dartExecutor), platformViewsController); mKeyboardManager = new KeyboardManager(this); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { mMouseCursorPlugin = new MouseCursorPlugin(this, new MouseCursorChannel(dartExecutor)); } else { mMouseCursorPlugin = null; @@ -516,7 +518,7 @@ private ZeroSides calculateShouldZeroSides() { return ZeroSides.RIGHT; } else if (rotation == Surface.ROTATION_270) { // In android API >= 23, the nav bar always appears on the "bottom" (USB) side. - return Build.VERSION.SDK_INT >= 23 ? ZeroSides.LEFT : ZeroSides.RIGHT; + return Build.VERSION.SDK_INT >= API_LEVELS.API_23 ? ZeroSides.LEFT : ZeroSides.RIGHT; } // Ambiguous orientation due to landscape left/right default. Zero both sides. else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) { @@ -560,7 +562,7 @@ private int guessBottomKeyboardInset(WindowInsets insets) { @SuppressLint({"InlinedApi", "NewApi"}) public final WindowInsets onApplyWindowInsets(WindowInsets insets) { // getSystemGestureInsets() was introduced in API 29 and immediately deprecated in 30. - if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { + if (Build.VERSION.SDK_INT == API_LEVELS.API_29) { Insets systemGestureInsets = insets.getSystemGestureInsets(); mMetrics.systemGestureInsetTop = systemGestureInsets.top; mMetrics.systemGestureInsetRight = systemGestureInsets.right; @@ -572,7 +574,7 @@ public final WindowInsets onApplyWindowInsets(WindowInsets insets) { boolean navigationBarVisible = (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) == 0; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) { int mask = 0; if (navigationBarVisible) { mask = mask | android.view.WindowInsets.Type.navigationBars(); @@ -789,8 +791,8 @@ private void releaseAccessibilityNodeProvider() { // -------- Start: Mouse ------- @Override - @TargetApi(Build.VERSION_CODES.N) - @RequiresApi(Build.VERSION_CODES.N) + @TargetApi(API_LEVELS.API_24) + @RequiresApi(API_LEVELS.API_24) @NonNull public PointerIcon getSystemPointerIcon(int type) { return PointerIcon.getSystemIcon(getContext(), type); diff --git a/shell/platform/android/test/io/flutter/embedding/android/AndroidTouchProcessorTest.java b/shell/platform/android/test/io/flutter/embedding/android/AndroidTouchProcessorTest.java index 68e1e7f167ff6..696b6daf85e52 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/AndroidTouchProcessorTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/AndroidTouchProcessorTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; import static junit.framework.TestCase.assertEquals; import static org.mockito.Mockito.inOrder; import static org.mockito.Mockito.mock; @@ -9,7 +10,6 @@ import android.annotation.TargetApi; import android.content.Context; -import android.os.Build; import android.view.InputDevice; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -30,7 +30,7 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(28) +@TargetApi(API_LEVELS.API_28) public class AndroidTouchProcessorTest { @Mock FlutterRenderer mockRenderer; AndroidTouchProcessor touchProcessor; @@ -351,7 +351,7 @@ public void unexpectedMaskedAction() { } @Test - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) public void scrollWheelAbove26() { // Pointer id must be zero to match actionIndex in mocked event. final int pointerId = 0; @@ -399,7 +399,7 @@ public void scrollWheelAbove26() { } @Test - @Config(sdk = {Build.VERSION_CODES.N_MR1}) + @Config(sdk = API_LEVELS.API_25) public void scrollWheelBelow26() { // Pointer id must be zero to match actionIndex in mocked event. final int pointerId = 0; diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java index f5b0d395341cd..d68564f2e2aa8 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterActivityTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; import static io.flutter.embedding.android.FlutterActivityLaunchConfigs.HANDLE_DEEPLINKING_META_DATA_KEY; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; @@ -20,7 +21,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.os.Build; import android.os.Bundle; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -89,7 +89,7 @@ public void flutterViewHasId() { // TODO(garyq): Robolectric does not yet support android api 33 yet. Switch to a robolectric // test that directly exercises the OnBackInvoked APIs when API 33 is supported. @Test - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) public void itRegistersOnBackInvokedCallbackOnChangingFrameworkHandlesBack() { Intent intent = FlutterActivityWithReportFullyDrawn.createDefaultIntent(ctx); ActivityController activityController = @@ -110,7 +110,7 @@ public void itRegistersOnBackInvokedCallbackOnChangingFrameworkHandlesBack() { // TODO(garyq): Robolectric does not yet support android api 33 yet. Switch to a robolectric // test that directly exercises the OnBackInvoked APIs when API 33 is supported. @Test - @TargetApi(33) + @TargetApi(API_LEVELS.API_33) public void itUnregistersOnBackInvokedCallbackOnRelease() { Intent intent = FlutterActivityWithReportFullyDrawn.createDefaultIntent(ctx); ActivityController activityController = @@ -485,7 +485,7 @@ public void itReleaseEngineWhenOnDestroy() { } @Test - @Config(minSdk = 21, maxSdk = Build.VERSION_CODES.P) + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_28) public void fullyDrawn_beforeAndroidQ() { Intent intent = FlutterActivityWithReportFullyDrawn.createDefaultIntent(ctx); ActivityController activityController = @@ -499,7 +499,7 @@ public void fullyDrawn_beforeAndroidQ() { } @Test - @Config(minSdk = Build.VERSION_CODES.Q) + @Config(minSdk = API_LEVELS.API_29) public void fullyDrawn_fromAndroidQ() { Intent intent = FlutterActivityWithReportFullyDrawn.createDefaultIntent(ctx); ActivityController activityController = diff --git a/shell/platform/android/test/io/flutter/embedding/android/FlutterTextureViewTest.java b/shell/platform/android/test/io/flutter/embedding/android/FlutterTextureViewTest.java index f6eccaa31b6f7..216c8ea161bb2 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/FlutterTextureViewTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/FlutterTextureViewTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -15,7 +16,7 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(30) +@TargetApi(API_LEVELS.API_30) public class FlutterTextureViewTest { @Test public void surfaceTextureListenerReleasesRenderer() { diff --git a/shell/platform/android/test/io/flutter/embedding/android/KeyChannelResponderTest.java b/shell/platform/android/test/io/flutter/embedding/android/KeyChannelResponderTest.java index 80379a21343b2..3528eb48f3050 100644 --- a/shell/platform/android/test/io/flutter/embedding/android/KeyChannelResponderTest.java +++ b/shell/platform/android/test/io/flutter/embedding/android/KeyChannelResponderTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.android; +import static io.flutter.Build.API_LEVELS; import static junit.framework.TestCase.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.doAnswer; @@ -19,7 +20,7 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(28) +@TargetApi(API_LEVELS.API_28) public class KeyChannelResponderTest { @Mock KeyEventChannel keyEventChannel; diff --git a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java index e40096e7b01c6..26e53ba16836d 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/FlutterJNITest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -28,7 +29,7 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(24) // LocaleList and scriptCode are API 24+. +@TargetApi(API_LEVELS.API_24) // LocaleList and scriptCode are API 24+. public class FlutterJNITest { @Test public void itAllowsFirstFrameListenersToRemoveThemselvesInline() { diff --git a/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java b/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java index 1d6bf535737fa..99ddf30acd31c 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/loader/FlutterLoaderTest.java @@ -5,6 +5,7 @@ package io.flutter.embedding.engine.loader; import static android.os.Looper.getMainLooper; +import static io.flutter.Build.API_LEVELS; import static junit.framework.TestCase.assertFalse; import static junit.framework.TestCase.assertTrue; import static org.mockito.Mockito.any; @@ -216,8 +217,8 @@ public void itSetsEnableImpellerFromMetaData() { } @Test - @TargetApi(23) - @Config(sdk = 23) + @TargetApi(API_LEVELS.API_23) + @Config(sdk = API_LEVELS.API_23) public void itReportsFpsToVsyncWaiterAndroidM() { FlutterJNI mockFlutterJNI = mock(FlutterJNI.class); FlutterLoader flutterLoader = new FlutterLoader(mockFlutterJNI); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureSurfaceProducerTest.java b/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureSurfaceProducerTest.java index fb97be732e42b..f0c2cfecef2d2 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureSurfaceProducerTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/renderer/SurfaceTextureSurfaceProducerTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.renderer; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.robolectric.Shadows.shadowOf; @@ -17,7 +18,7 @@ import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) -@TargetApi(26) +@TargetApi(API_LEVELS.API_26) public final class SurfaceTextureSurfaceProducerTest { private final FlutterJNI fakeJNI = mock(FlutterJNI.class); diff --git a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/AccessibilityChannelTest.java b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/AccessibilityChannelTest.java index 5ee17c647983a..344f1557fc141 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/AccessibilityChannelTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/AccessibilityChannelTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -19,7 +20,7 @@ manifest = Config.NONE, shadows = {}) @RunWith(RobolectricTestRunner.class) -@TargetApi(24) +@TargetApi(API_LEVELS.API_24) public class AccessibilityChannelTest { @Test public void repliesWhenNoAccessibilityHandler() throws JSONException { diff --git a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/KeyEventChannelTest.java b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/KeyEventChannelTest.java index 32b328e9307aa..7dd4de7d42c09 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/KeyEventChannelTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/KeyEventChannelTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -35,7 +36,7 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(24) +@TargetApi(API_LEVELS.API_24) public class KeyEventChannelTest { KeyEvent keyEvent; diff --git a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/RestorationChannelTest.java b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/RestorationChannelTest.java index a58c098990cf2..88f928dcfc6ff 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/RestorationChannelTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/RestorationChannelTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.eq; @@ -24,7 +25,7 @@ manifest = Config.NONE, shadows = {}) @RunWith(AndroidJUnit4.class) -@TargetApi(24) +@TargetApi(API_LEVELS.API_24) public class RestorationChannelTest { @Test public void itDoesNotDoAnythingWhenRestorationDataIsSetBeforeFrameworkAsks() diff --git a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/SettingsChannelTest.java b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/SettingsChannelTest.java index 50c40e609ed06..0831f9509fd0d 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/SettingsChannelTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/SettingsChannelTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; import static junit.framework.TestCase.assertEquals; import static org.mockito.Mockito.eq; import static org.mockito.Mockito.isNull; @@ -21,8 +22,8 @@ @RunWith(AndroidJUnit4.class) public class SettingsChannelTest { @Test - @TargetApi(33) - @Config(sdk = 33) + @TargetApi(API_LEVELS.API_33) + @Config(sdk = API_LEVELS.API_33) @SuppressWarnings("deprecation") // DartExecutor.send is deprecated. public void setDisplayMetricsDoesNothingOnAPILevel33() { diff --git a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java index 067b5d183b54c..0194ce0328795 100644 --- a/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java +++ b/shell/platform/android/test/io/flutter/embedding/engine/systemchannels/TextInputChannelTest.java @@ -1,5 +1,6 @@ package io.flutter.embedding.engine.systemchannels; +import static io.flutter.Build.API_LEVELS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; @@ -19,7 +20,7 @@ manifest = Config.NONE, shadows = {}) @RunWith(AndroidJUnit4.class) -@TargetApi(24) +@TargetApi(API_LEVELS.API_24) public class TextInputChannelTest { @Test public void setEditableSizeAndTransformCompletes() throws JSONException { diff --git a/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java b/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java index 4fce566fc1655..cc04befc45d9e 100644 --- a/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/editing/TextInputPluginTest.java @@ -1,5 +1,6 @@ package io.flutter.plugin.editing; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertThrows; @@ -1388,7 +1389,7 @@ public void inputConnection_textInputTypeMultilineAndSuggestionsDisabled() { // -------- Start: Autofill Tests ------- @Test public void autofill_enabledByDefault() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } FlutterView testView = new FlutterView(ctx); @@ -1448,7 +1449,7 @@ public void autofill_enabledByDefault() { @Test public void autofill_canBeDisabled() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } FlutterView testView = new FlutterView(ctx); @@ -1485,7 +1486,7 @@ public void autofill_canBeDisabled() { @Test public void autofill_hintText() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } FlutterView testView = new FlutterView(ctx); @@ -1526,11 +1527,11 @@ public void autofill_hintText() { verify(children[0]).setHint("placeholder"); } - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @SuppressWarnings("deprecation") @Test public void autofill_onProvideVirtualViewStructure() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } FlutterView testView = getTestView(); @@ -1618,10 +1619,10 @@ public void autofill_onProvideVirtualViewStructure() { } @SuppressWarnings("deprecation") - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @Test public void autofill_onProvideVirtualViewStructure_singular_textfield() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } // Migrate to ActivityScenario by following https://github.com/robolectric/robolectric/pull/4736 @@ -1670,10 +1671,10 @@ public void autofill_onProvideVirtualViewStructure_singular_textfield() { verify(children[0]).setDimens(anyInt(), anyInt(), anyInt(), anyInt(), gt(0), gt(0)); } - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @Test public void autofill_testLifeCycle() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } @@ -1805,11 +1806,11 @@ public void autofill_testLifeCycle() { assertEquals("1".hashCode(), testAfm.exitId); } - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @SuppressWarnings("deprecation") @Test public void autofill_testAutofillUpdatesTheFramework() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } @@ -1903,10 +1904,10 @@ public void autofill_testAutofillUpdatesTheFramework() { assertEquals(editState.text, "unfocused field"); } - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @Test public void autofill_doesNotCrashAfterClearClientCall() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } FlutterView testView = new FlutterView(ctx); @@ -1952,10 +1953,10 @@ public void autofill_doesNotCrashAfterClearClientCall() { .updateEditingState(anyInt(), any(), anyInt(), anyInt(), anyInt(), anyInt()); } - @Config(minSdk = Build.VERSION_CODES.O) + @Config(minSdk = API_LEVELS.API_26) @Test public void autofill_testSetTextIpnutClientUpdatesSideFields() { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } @@ -2132,8 +2133,8 @@ public void sendAppPrivateCommand_hasData() throws JSONException { } @Test - @TargetApi(30) - @Config(sdk = 30) + @TargetApi(API_LEVELS.API_30) + @Config(sdk = API_LEVELS.API_30) @SuppressWarnings("deprecation") // getWindowSystemUiVisibility, SYSTEM_UI_FLAG_LAYOUT_STABLE. // flutter#133074 tracks migration work. @@ -2211,8 +2212,8 @@ public void ime_windowInsetsSync_notLaidOutBehindNavigation_excludesNavigationBa } @Test - @TargetApi(30) - @Config(sdk = 30) + @TargetApi(API_LEVELS.API_30) + @Config(sdk = API_LEVELS.API_30) @SuppressWarnings("deprecation") // getWindowSystemUiVisibility // flutter#133074 tracks migration work. @@ -2292,8 +2293,8 @@ public void ime_windowInsetsSync_laidOutBehindNavigation_includesNavigationBars( } @Test - @TargetApi(30) - @Config(sdk = 30) + @TargetApi(API_LEVELS.API_30) + @Config(sdk = API_LEVELS.API_30) @SuppressWarnings("deprecation") // getWindowSystemUiVisibility, SYSTEM_UI_FLAG_LAYOUT_STABLE // flutter#133074 tracks migration work. @@ -2481,7 +2482,7 @@ public void notifyViewExited(View view, int virtualId) { } public void notifyValueChanged(View view, int virtualId, AutofillValue value) { - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT < API_LEVELS.API_26) { return; } changeVirtualId = virtualId; diff --git a/shell/platform/android/test/io/flutter/plugin/localization/LocalizationPluginTest.java b/shell/platform/android/test/io/flutter/plugin/localization/LocalizationPluginTest.java index 3f40c47646e1c..ca81eddd66b1a 100644 --- a/shell/platform/android/test/io/flutter/plugin/localization/LocalizationPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/localization/LocalizationPluginTest.java @@ -1,5 +1,6 @@ package io.flutter.plugin.localization; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; @@ -10,7 +11,6 @@ import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; -import android.os.Build; import android.os.LocaleList; import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -28,13 +28,13 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(24) // LocaleList and scriptCode are API 24+. +@TargetApi(API_LEVELS.API_24) // LocaleList and scriptCode are API 24+. public class LocalizationPluginTest { private final Context ctx = ApplicationProvider.getApplicationContext(); // This test should be synced with the version for API 24. @Test - @Config(sdk = Build.VERSION_CODES.O) + @Config(sdk = API_LEVELS.API_26) public void computePlatformResolvedLocaleAPI26() { // --- Test Setup --- FlutterJNI flutterJNI = new FlutterJNI(); @@ -142,7 +142,7 @@ public void computePlatformResolvedLocaleAPI26() { // This test should be synced with the version for API 26. @Test - @Config(minSdk = Build.VERSION_CODES.N) + @Config(minSdk = API_LEVELS.API_24) public void computePlatformResolvedLocale_fromAndroidN() { // --- Test Setup --- FlutterJNI flutterJNI = new FlutterJNI(); @@ -237,10 +237,7 @@ public void computePlatformResolvedLocale_fromAndroidN() { // Tests the legacy pre API 24 algorithm. @Test - @Config( - minSdk = Build.VERSION_CODES.LOLLIPOP, - maxSdk = Build.VERSION_CODES.M, - qualifiers = "es-rMX") + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_23, qualifiers = "es-rMX") public void computePlatformResolvedLocale_emptySupportedLocales_beforeAndroidN() { FlutterJNI flutterJNI = new FlutterJNI(); DartExecutor dartExecutor = mock(DartExecutor.class); @@ -252,7 +249,7 @@ public void computePlatformResolvedLocale_emptySupportedLocales_beforeAndroidN() } @Test - @Config(minSdk = 21, maxSdk = Build.VERSION_CODES.M, qualifiers = "") + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_23, qualifiers = "") public void computePlatformResolvedLocale_selectFirstLocaleWhenNoUserSetting_beforeAndroidN() { FlutterJNI flutterJNI = new FlutterJNI(); DartExecutor dartExecutor = mock(DartExecutor.class); @@ -272,7 +269,7 @@ public void computePlatformResolvedLocale_selectFirstLocaleWhenNoUserSetting_bef } @Test - @Config(minSdk = 21, maxSdk = Build.VERSION_CODES.M, qualifiers = "fr-rCH") + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_23, qualifiers = "fr-rCH") public void computePlatformResolvedLocale_selectFirstLocaleWhenNoExactMatch_beforeAndroidN() { FlutterJNI flutterJNI = new FlutterJNI(); DartExecutor dartExecutor = mock(DartExecutor.class); @@ -295,7 +292,7 @@ public void computePlatformResolvedLocale_selectFirstLocaleWhenNoExactMatch_befo } @Test - @Config(minSdk = 21, maxSdk = Build.VERSION_CODES.M, qualifiers = "it-rIT") + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_23, qualifiers = "it-rIT") public void computePlatformResolvedLocale_selectExactMatchLocale_beforeAndroidN() { FlutterJNI flutterJNI = new FlutterJNI(); DartExecutor dartExecutor = mock(DartExecutor.class); @@ -318,7 +315,7 @@ public void computePlatformResolvedLocale_selectExactMatchLocale_beforeAndroidN( } @Test - @Config(minSdk = 21, maxSdk = Build.VERSION_CODES.M, qualifiers = "fr-rCH") + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_23, qualifiers = "fr-rCH") public void computePlatformResolvedLocale_selectOnlyLanguageLocale_beforeAndroidN() { FlutterJNI flutterJNI = new FlutterJNI(); DartExecutor dartExecutor = mock(DartExecutor.class); diff --git a/shell/platform/android/test/io/flutter/plugin/mouse/MouseCursorPluginTest.java b/shell/platform/android/test/io/flutter/plugin/mouse/MouseCursorPluginTest.java index 5ab0f07f65d02..11feb418538c4 100644 --- a/shell/platform/android/test/io/flutter/plugin/mouse/MouseCursorPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/mouse/MouseCursorPluginTest.java @@ -1,5 +1,6 @@ package io.flutter.plugin.mouse; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.mock; @@ -25,10 +26,10 @@ @Config( manifest = Config.NONE, - minSdk = 24, + minSdk = API_LEVELS.API_24, shadows = {}) @RunWith(AndroidJUnit4.class) -@TargetApi(24) +@TargetApi(API_LEVELS.API_24) public class MouseCursorPluginTest { @SuppressWarnings("deprecation") diff --git a/shell/platform/android/test/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTargetTest.java b/shell/platform/android/test/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTargetTest.java index 5f73328969e08..11df94d395ef9 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTargetTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/ImageReaderPlatformViewRenderTargetTest.java @@ -5,6 +5,7 @@ package io.flutter.plugin.platform; import static android.os.Looper.getMainLooper; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -24,7 +25,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -@TargetApi(29) +@TargetApi(API_LEVELS.API_29) @RunWith(AndroidJUnit4.class) public class ImageReaderPlatformViewRenderTargetTest { private final Context ctx = ApplicationProvider.getApplicationContext(); diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java index dfb2f57cbd4b0..36b497bc55f80 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformPluginTest.java @@ -6,6 +6,7 @@ import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -210,7 +211,7 @@ public void platformPlugin_getClipboardDataIsNullWhenItemHasNoTextNorUri() throw @SuppressWarnings("deprecation") // ClipboardManager.getText - @Config(sdk = Build.VERSION_CODES.P) + @Config(sdk = API_LEVELS.API_28) @Test public void platformPlugin_hasStrings() { View fakeDecorView = mock(View.class); @@ -250,7 +251,7 @@ public void platformPlugin_hasStrings() { clipboardManager.setPrimaryClip(clip); assertFalse(platformPlugin.mPlatformMessageHandler.clipboardHasStrings()); - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { // Empty clipboard clipboardManager.clearPrimaryClip(); assertFalse(platformPlugin.mPlatformMessageHandler.clipboardHasStrings()); @@ -261,7 +262,7 @@ public void platformPlugin_hasStrings() { verify(clipboardManager, never()).getText(); } - @Config(sdk = Build.VERSION_CODES.Q) + @Config(sdk = API_LEVELS.API_29) @Test public void setNavigationBarDividerColor() { View fakeDecorView = mock(View.class); @@ -271,7 +272,7 @@ public void setNavigationBarDividerColor() { when(mockActivity.getWindow()).thenReturn(fakeWindow); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { // Default style test SystemChromeStyle style = new SystemChromeStyle( @@ -335,7 +336,7 @@ public void setNavigationBarDividerColor() { } } - @Config(sdk = Build.VERSION_CODES.R) + @Config(sdk = API_LEVELS.API_30) @Test public void setNavigationBarIconBrightness() { View fakeDecorView = mock(View.class); @@ -345,7 +346,7 @@ public void setNavigationBarIconBrightness() { when(mockActivity.getWindow()).thenReturn(fakeWindow); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); - if (Build.VERSION.SDK_INT >= 30) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) { WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class); when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController); @@ -382,7 +383,7 @@ public void setNavigationBarIconBrightness() { } } - @Config(sdk = Build.VERSION_CODES.R) + @Config(sdk = API_LEVELS.API_30) @Test public void setStatusBarIconBrightness() { View fakeDecorView = mock(View.class); @@ -392,7 +393,7 @@ public void setStatusBarIconBrightness() { when(mockActivity.getWindow()).thenReturn(fakeWindow); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); - if (Build.VERSION.SDK_INT >= 30) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_30) { WindowInsetsController fakeWindowInsetsController = mock(WindowInsetsController.class); when(fakeWindow.getInsetsController()).thenReturn(fakeWindowInsetsController); @@ -429,7 +430,7 @@ public void setStatusBarIconBrightness() { @SuppressWarnings("deprecation") // SYSTEM_UI_FLAG_*, setSystemUiVisibility - @Config(sdk = Build.VERSION_CODES.Q) + @Config(sdk = API_LEVELS.API_29) @Test public void setSystemUiMode() { View fakeDecorView = mock(View.class); @@ -439,7 +440,7 @@ public void setSystemUiMode() { when(mockActivity.getWindow()).thenReturn(fakeWindow); PlatformPlugin platformPlugin = new PlatformPlugin(mockActivity, mockPlatformChannel); - if (Build.VERSION.SDK_INT >= 28) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_28) { platformPlugin.mPlatformMessageHandler.showSystemUiMode( PlatformChannel.SystemUiMode.LEAN_BACK); verify(fakeDecorView) @@ -473,7 +474,7 @@ public void setSystemUiMode() { | View.SYSTEM_UI_FLAG_FULLSCREEN); } - if (Build.VERSION.SDK_INT >= 29) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_29) { platformPlugin.mPlatformMessageHandler.showSystemUiMode( PlatformChannel.SystemUiMode.EDGE_TO_EDGE); verify(fakeDecorView) @@ -542,7 +543,7 @@ public void setSystemUiModeListener_overlaysAreVisible() { @SuppressWarnings("deprecation") // SYSTEM_UI_FLAG_*, setSystemUiVisibility - @Config(sdk = Build.VERSION_CODES.P) + @Config(sdk = API_LEVELS.API_28) @Test public void doNotEnableEdgeToEdgeOnOlderSdk() { View fakeDecorView = mock(View.class); @@ -563,7 +564,7 @@ public void doNotEnableEdgeToEdgeOnOlderSdk() { @SuppressWarnings("deprecation") // FLAG_TRANSLUCENT_STATUS, FLAG_TRANSLUCENT_NAVIGATION - @Config(sdk = Build.VERSION_CODES.Q) + @Config(sdk = API_LEVELS.API_29) @Test public void verifyWindowFlagsSetToStyleOverlays() { View fakeDecorView = mock(View.class); diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java index 2bfe689abfec4..64fd84f93743b 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewWrapperTest.java @@ -5,6 +5,7 @@ package io.flutter.plugin.platform; import static android.view.View.OnFocusChangeListener; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -29,7 +30,7 @@ import org.robolectric.annotation.Implementation; import org.robolectric.annotation.Implements; -@TargetApi(31) +@TargetApi(API_LEVELS.API_31) @RunWith(AndroidJUnit4.class) public class PlatformViewWrapperTest { private final Context ctx = ApplicationProvider.getApplicationContext(); diff --git a/shell/platform/android/test/io/flutter/plugin/platform/SingleViewPresentationTest.java b/shell/platform/android/test/io/flutter/plugin/platform/SingleViewPresentationTest.java index fa07fa117136b..592a9f22bbeec 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/SingleViewPresentationTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/SingleViewPresentationTest.java @@ -4,8 +4,7 @@ package io.flutter.plugin.platform; -import static android.os.Build.VERSION_CODES.P; -import static android.os.Build.VERSION_CODES.R; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.spy; @@ -24,10 +23,10 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(P) +@TargetApi(API_LEVELS.API_28) public class SingleViewPresentationTest { @Test - @Config(minSdk = 21, maxSdk = R) + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_30) public void returnsOuterContextInputMethodManager() { // There's a bug in Android Q caused by the IMM being instanced per display. // https://github.com/flutter/flutter/issues/38375. We need the context returned by @@ -58,7 +57,7 @@ public void returnsOuterContextInputMethodManager() { } @Test - @Config(minSdk = 21, maxSdk = R) + @Config(minSdk = API_LEVELS.API_21, maxSdk = API_LEVELS.API_30) public void returnsOuterContextInputMethodManager_createDisplayContext() { // The IMM should also persist across display contexts created from the base context. diff --git a/shell/platform/android/test/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTargetTest.java b/shell/platform/android/test/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTargetTest.java index 2f086f6f73edb..1921c935b7a8c 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTargetTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/SurfaceTexturePlatformViewRenderTargetTest.java @@ -4,6 +4,7 @@ package io.flutter.plugin.platform; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -21,7 +22,7 @@ import org.junit.Test; import org.junit.runner.RunWith; -@TargetApi(31) +@TargetApi(API_LEVELS.API_31) @RunWith(AndroidJUnit4.class) public class SurfaceTexturePlatformViewRenderTargetTest { private final Context ctx = ApplicationProvider.getApplicationContext(); diff --git a/shell/platform/android/test/io/flutter/plugin/platform/WindowManagerHandlerTest.java b/shell/platform/android/test/io/flutter/plugin/platform/WindowManagerHandlerTest.java index c7fd1d353f8a8..7e37231774ca9 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/WindowManagerHandlerTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/WindowManagerHandlerTest.java @@ -4,9 +4,7 @@ package io.flutter.plugin.platform; -import static android.os.Build.VERSION_CODES.P; -import static android.os.Build.VERSION_CODES.R; -import static android.os.Build.VERSION_CODES.S; +import static io.flutter.Build.API_LEVELS; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoInteractions; @@ -24,10 +22,10 @@ @Config(manifest = Config.NONE) @RunWith(AndroidJUnit4.class) -@TargetApi(P) +@TargetApi(API_LEVELS.API_28) public class WindowManagerHandlerTest { @Test - @Config(minSdk = R) + @Config(minSdk = API_LEVELS.API_30) public void windowManagerHandler_passesCorrectlyToFakeWindowViewGroup() { // Mock the WindowManager and FakeWindowViewGroup that get used by the WindowManagerHandler. WindowManager mockWindowManager = mock(WindowManager.class); @@ -63,7 +61,7 @@ public void windowManagerHandler_passesCorrectlyToFakeWindowViewGroup() { } @Test - @Config(minSdk = R) + @Config(minSdk = API_LEVELS.API_30) public void windowManagerHandler_logAndReturnEarly_whenFakeWindowViewGroupIsNull() { // Mock the WindowManager and FakeWindowViewGroup that get used by the WindowManagerHandler. WindowManager mockWindowManager = mock(WindowManager.class); @@ -95,7 +93,7 @@ public void windowManagerHandler_logAndReturnEarly_whenFakeWindowViewGroupIsNull // delegate WindowManager. Because this must include some deprecated WindowManager method calls // (because the proxy overrides every method), we suppress deprecation warnings here. @Test - @Config(minSdk = S) + @Config(minSdk = API_LEVELS.API_31) @SuppressWarnings("deprecation") public void windowManagerHandler_forwardsAllOtherCallsToDelegate() { // Mock the WindowManager and FakeWindowViewGroup that get used by the WindowManagerHandler. diff --git a/shell/platform/android/test/io/flutter/plugin/text/ProcessTextPluginTest.java b/shell/platform/android/test/io/flutter/plugin/text/ProcessTextPluginTest.java index e582f9b8c8fb8..8891e72cdbfcf 100644 --- a/shell/platform/android/test/io/flutter/plugin/text/ProcessTextPluginTest.java +++ b/shell/platform/android/test/io/flutter/plugin/text/ProcessTextPluginTest.java @@ -1,5 +1,6 @@ package io.flutter.plugin.text; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; @@ -15,7 +16,6 @@ import android.content.pm.PackageItemInfo; import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; -import android.os.Build; import androidx.annotation.RequiresApi; import androidx.test.ext.junit.runners.AndroidJUnit4; import io.flutter.embedding.engine.dart.DartExecutor; @@ -36,8 +36,8 @@ import org.mockito.ArgumentCaptor; @RunWith(AndroidJUnit4.class) -@TargetApi(Build.VERSION_CODES.N) -@RequiresApi(Build.VERSION_CODES.N) +@TargetApi(API_LEVELS.API_24) +@RequiresApi(API_LEVELS.API_24) public class ProcessTextPluginTest { private static void sendToBinaryMessageHandler( diff --git a/shell/platform/android/test/io/flutter/util/HandlerCompatTest.java b/shell/platform/android/test/io/flutter/util/HandlerCompatTest.java index df1352aee666f..9d4538d40565d 100644 --- a/shell/platform/android/test/io/flutter/util/HandlerCompatTest.java +++ b/shell/platform/android/test/io/flutter/util/HandlerCompatTest.java @@ -4,6 +4,7 @@ package io.flutter.util; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertTrue; import android.os.Handler; @@ -17,7 +18,7 @@ @RunWith(RobolectricTestRunner.class) public class HandlerCompatTest { @Test - @Config(sdk = 28) + @Config(sdk = API_LEVELS.API_28) public void createAsync_createsAnAsyncHandler() { Handler handler = Handler.createAsync(Looper.getMainLooper()); diff --git a/shell/platform/android/test/io/flutter/util/PathUtilsTest.java b/shell/platform/android/test/io/flutter/util/PathUtilsTest.java index 47288f973a9c6..08e5a1aaac990 100644 --- a/shell/platform/android/test/io/flutter/util/PathUtilsTest.java +++ b/shell/platform/android/test/io/flutter/util/PathUtilsTest.java @@ -4,6 +4,7 @@ package io.flutter.util; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.mock; @@ -34,7 +35,7 @@ public void canGetFilesDir() { public void canOnlyGetFilesPathWhenDiskFullAndFilesDirNotCreated() { Context context = mock(Context.class); when(context.getFilesDir()).thenReturn(null); - if (Build.VERSION.SDK_INT >= 24) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { when(context.getDataDir()).thenReturn(new File(APP_DATA_PATH)); } else { when(context.getApplicationInfo().dataDir).thenReturn(APP_DATA_PATH); @@ -54,7 +55,7 @@ public void canGetFlutterDataDir() { public void canOnlyGetFlutterDataPathWhenDiskFullAndFlutterDataDirNotCreated() { Context context = mock(Context.class); when(context.getDir("flutter", Context.MODE_PRIVATE)).thenReturn(null); - if (Build.VERSION.SDK_INT >= 24) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { when(context.getDataDir()).thenReturn(new File(APP_DATA_PATH)); } else { when(context.getApplicationInfo().dataDir).thenReturn(APP_DATA_PATH); @@ -66,7 +67,7 @@ public void canOnlyGetFlutterDataPathWhenDiskFullAndFlutterDataDirNotCreated() { public void canGetCacheDir() { Context context = mock(Context.class); when(context.getCacheDir()).thenReturn(new File(APP_DATA_PATH + "/cache")); - if (Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_21) { when(context.getCodeCacheDir()).thenReturn(new File(APP_DATA_PATH + "/code_cache")); } assertTrue(PathUtils.getCacheDirectory(context).startsWith(APP_DATA_PATH)); @@ -76,10 +77,10 @@ public void canGetCacheDir() { public void canOnlyGetCachePathWhenDiskFullAndCacheDirNotCreated() { Context context = mock(Context.class); when(context.getCacheDir()).thenReturn(null); - if (Build.VERSION.SDK_INT >= 21) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_21) { when(context.getCodeCacheDir()).thenReturn(null); } - if (Build.VERSION.SDK_INT >= 24) { + if (Build.VERSION.SDK_INT >= API_LEVELS.API_24) { when(context.getDataDir()).thenReturn(new File(APP_DATA_PATH)); } else { when(context.getApplicationInfo().dataDir).thenReturn(APP_DATA_PATH); diff --git a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java index 42be60d6d104e..389c329f96c45 100644 --- a/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java +++ b/shell/platform/android/test/io/flutter/view/AccessibilityBridgeTest.java @@ -4,6 +4,7 @@ package io.flutter.view; +import static io.flutter.Build.API_LEVELS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; @@ -80,8 +81,8 @@ public void itDescribesNonTextFieldsWithAContentDescription() { assertEquals(nodeInfo.getText(), null); } - @Config(sdk = 28) - @TargetApi(28) + @Config(sdk = API_LEVELS.API_28) + @TargetApi(API_LEVELS.API_28) @Test public void itDescribesTextFieldsWithTextAndHint() { AccessibilityBridge accessibilityBridge = setUpBridge(); @@ -322,8 +323,8 @@ public void itSetsTraversalAfter() { verify(mockNodeInfo2, times(1)).setTraversalAfter(eq(mockRootView), eq(1)); } - @Config(sdk = 24) - @TargetApi(24) + @Config(sdk = API_LEVELS.API_24) + @TargetApi(API_LEVELS.API_24) @Test public void itSetsRootViewNotImportantForAccessibility() { AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class); @@ -351,8 +352,8 @@ public void itSetsRootViewNotImportantForAccessibility() { verify(mockNodeInfo, times(1)).setImportantForAccessibility(eq(false)); } - @Config(sdk = 24) - @TargetApi(24) + @Config(sdk = API_LEVELS.API_24) + @TargetApi(API_LEVELS.API_24) @Test public void itSetsNodeImportantForAccessibilityIfItHasContent() { AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class); @@ -382,8 +383,8 @@ public void itSetsNodeImportantForAccessibilityIfItHasContent() { verify(mockNodeInfo, times(1)).setImportantForAccessibility(eq(true)); } - @Config(sdk = 24) - @TargetApi(24) + @Config(sdk = API_LEVELS.API_24) + @TargetApi(API_LEVELS.API_24) @Test public void itSetsNodeImportantForAccessibilityIfItHasActions() { AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class); @@ -413,8 +414,8 @@ public void itSetsNodeImportantForAccessibilityIfItHasActions() { verify(mockNodeInfo, times(1)).setImportantForAccessibility(eq(true)); } - @Config(sdk = 24) - @TargetApi(24) + @Config(sdk = API_LEVELS.API_24) + @TargetApi(API_LEVELS.API_24) @Test public void itSetsNodeUnImportantForAccessibilityIfItIsEmpty() { AccessibilityViewEmbedder mockViewEmbedder = mock(AccessibilityViewEmbedder.class); @@ -455,8 +456,8 @@ public void itSetsNodeUnImportantForAccessibilityIfItIsEmpty() { @SuppressWarnings("deprecation") // getSystemWindowInset* methods deprecated. - @Config(sdk = 28) - @TargetApi(28) + @Config(sdk = API_LEVELS.API_28) + @TargetApi(API_LEVELS.API_28) @Test public void itSetCutoutInsetBasedonLayoutModeNever() { int expectedInsetLeft = 5; @@ -507,8 +508,8 @@ public void itSetCutoutInsetBasedonLayoutModeNever() { @SuppressWarnings("deprecation") // getSystemWindowInset* methods deprecated. - @Config(sdk = 28) - @TargetApi(28) + @Config(sdk = API_LEVELS.API_28) + @TargetApi(API_LEVELS.API_28) @Test public void itSetCutoutInsetBasedonLayoutModeDefault() { int expectedInsetLeft = 5; @@ -559,8 +560,8 @@ public void itSetCutoutInsetBasedonLayoutModeDefault() { @SuppressWarnings("deprecation") // getSystemWindowInset* methods deprecated. - @Config(sdk = 28) - @TargetApi(28) + @Config(sdk = API_LEVELS.API_28) + @TargetApi(API_LEVELS.API_28) @Test public void itSetCutoutInsetBasedonLayoutModeShortEdges() { int expectedInsetLeft = 5; @@ -611,8 +612,8 @@ public void itSetCutoutInsetBasedonLayoutModeShortEdges() { @SuppressWarnings("deprecation") // getSystemWindowInset* methods deprecated. // fluter#133074 tracks post deprecation work. - @Config(sdk = 30) - @TargetApi(30) + @Config(sdk = API_LEVELS.API_30) + @TargetApi(API_LEVELS.API_30) @Test public void itSetCutoutInsetBasedonLayoutModeAlways() { int expectedInsetLeft = 5; @@ -857,7 +858,7 @@ public void itAnnouncesRouteNameWhenRemoveARoute() { verify(mockRootView, times(1)).setAccessibilityPaneTitle(eq("new_node2")); } - @Config(sdk = 21) + @Config(sdk = API_LEVELS.API_21) @Test public void itCanPerformSetText() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -896,7 +897,7 @@ public void itCanPerformSetText() { .dispatchSemanticsAction(1, AccessibilityBridge.Action.SET_TEXT, expectedText); } - @Config(sdk = 21) + @Config(sdk = API_LEVELS.API_21) @Test public void itCanPredictSetText() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -935,7 +936,7 @@ public void itCanPredictSetText() { assertEquals(nodeInfo.getText().toString(), expectedText); } - @Config(sdk = 21) + @Config(sdk = API_LEVELS.API_21) @Test public void itBuildsAttributedString() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -1001,7 +1002,7 @@ public void itBuildsAttributedString() { assertEquals(actual.getSpanEnd(spellOutSpan), 9); } - @Config(sdk = 21) + @Config(sdk = API_LEVELS.API_21) @Test public void itSetsTextCorrectly() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -1060,8 +1061,8 @@ public void itSetsTextCorrectly() { assertEquals(objectSpans.length, 0); } - @Config(sdk = 28) - @TargetApi(28) + @Config(sdk = API_LEVELS.API_28) + @TargetApi(API_LEVELS.API_28) @Test public void itSetsTooltipCorrectly() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -1098,7 +1099,7 @@ public void itSetsTooltipCorrectly() { assertEquals(actual.toString(), root.tooltip); } - @TargetApi(28) + @TargetApi(API_LEVELS.API_28) @Test public void itSetsIdentifierCorrectly() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -1136,7 +1137,7 @@ public void itSetsIdentifierCorrectly() { assertEquals(actual.toString(), root.identifier); } - @Config(sdk = 21) + @Config(sdk = API_LEVELS.API_21) @Test public void itCanCreateAccessibilityNodeInfoWithSetText() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); @@ -1318,8 +1319,8 @@ public void itSetsFocusabilityBasedOnFlagsCorrectly() { assertTrue(node2Info.isFocusable()); } - @Config(sdk = 31) - @TargetApi(31) + @Config(sdk = API_LEVELS.API_31) + @TargetApi(API_LEVELS.API_31) @Test public void itSetsBoldTextFlagCorrectly() { AccessibilityChannel mockChannel = mock(AccessibilityChannel.class); diff --git a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/ExternalTextureTests.java b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/ExternalTextureTests.java index 605a07a3b6606..dd02b4956edcb 100644 --- a/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/ExternalTextureTests.java +++ b/testing/scenario_app/android/app/src/androidTest/java/dev/flutter/scenariosui/ExternalTextureTests.java @@ -4,9 +4,10 @@ package dev.flutter.scenariosui; +import static io.flutter.Build.API_LEVELS; + import android.content.Intent; import android.graphics.Rect; -import android.os.Build.VERSION_CODES; import androidx.annotation.NonNull; import androidx.test.filters.LargeTest; import androidx.test.filters.SdkSuppress; @@ -82,7 +83,7 @@ public void testRotatedMediaSurface_270() throws Exception { } @Test - @SdkSuppress(minSdkVersion = VERSION_CODES.M) + @SdkSuppress(minSdkVersion = API_LEVELS.API_23) public void testCroppedMediaSurface_bottomLeft() throws Exception { intent.putExtra("scenario_name", "display_texture"); intent.putExtra("surface_renderer", "image"); @@ -93,7 +94,7 @@ public void testCroppedMediaSurface_bottomLeft() throws Exception { } @Test - @SdkSuppress(minSdkVersion = VERSION_CODES.M) + @SdkSuppress(minSdkVersion = API_LEVELS.API_23) public void testCroppedMediaSurface_topRight() throws Exception { intent.putExtra("scenario_name", "display_texture"); intent.putExtra("surface_renderer", "image"); @@ -105,7 +106,7 @@ public void testCroppedMediaSurface_topRight() throws Exception { } @Test - @SdkSuppress(minSdkVersion = VERSION_CODES.M) + @SdkSuppress(minSdkVersion = API_LEVELS.API_23) public void testCroppedRotatedMediaSurface_bottomLeft_90() throws Exception { intent.putExtra("scenario_name", "display_texture"); intent.putExtra("surface_renderer", "image"); diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java index fcced923eb563..c2a018eb881f9 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/ExternalTextureFlutterActivity.java @@ -4,6 +4,8 @@ package dev.flutter.scenarios; +import static io.flutter.Build.API_LEVELS; + import android.content.res.AssetFileDescriptor; import android.graphics.Canvas; import android.graphics.ImageFormat; @@ -19,7 +21,6 @@ import android.media.MediaExtractor; import android.media.MediaFormat; import android.os.Build.VERSION; -import android.os.Build.VERSION_CODES; import android.os.Bundle; import android.os.Handler; import android.os.HandlerThread; @@ -102,7 +103,7 @@ public void waitUntilFlutterRendered() { private SurfaceRenderer selectSurfaceRenderer(String surfaceRenderer, Bundle extras) { switch (surfaceRenderer) { case "image": - if (VERSION.SDK_INT >= VERSION_CODES.M) { + if (VERSION.SDK_INT >= API_LEVELS.API_23) { // CanvasSurfaceRenderer doesn't work correctly when used with ImageSurfaceRenderer. // Use MediaSurfaceRenderer for now. return new ImageSurfaceRenderer( @@ -186,7 +187,7 @@ public void attach(Surface surface, CountDownLatch onFirstFrame) { @Override public void repaint() { Canvas canvas = - VERSION.SDK_INT >= VERSION_CODES.M + VERSION.SDK_INT >= API_LEVELS.API_23 ? surface.lockHardwareCanvas() : surface.lockCanvas(null); Paint paint = new Paint(); @@ -337,7 +338,7 @@ public void destroy() { * Takes frames from the inner SurfaceRenderer and feeds it through an ImageReader and ImageWriter * pair. */ - @RequiresApi(VERSION_CODES.M) + @RequiresApi(API_LEVELS.API_23) private static class ImageSurfaceRenderer implements SurfaceRenderer { private final SurfaceRenderer inner; private final Rect crop; @@ -360,7 +361,7 @@ protected ImageSurfaceRenderer(SurfaceRenderer inner, Rect crop) { @Override public void attach(Surface surface, CountDownLatch onFirstFrame) { this.onFirstFrame = onFirstFrame; - if (VERSION.SDK_INT >= VERSION_CODES.Q) { + if (VERSION.SDK_INT >= API_LEVELS.API_29) { // On Android Q+, use PRIVATE image format. // Also let the frame producer know the images will // be sampled from by the GPU. diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java index 399afdf1be6b9..0524d3428be88 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/SurfacePlatformViewFactory.java @@ -4,6 +4,8 @@ package dev.flutter.scenarios; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.content.Context; import android.content.ContextWrapper; @@ -23,7 +25,7 @@ import io.flutter.plugin.platform.PlatformViewFactory; import java.nio.ByteBuffer; -@TargetApi(23) +@TargetApi(API_LEVELS.API_23) public final class SurfacePlatformViewFactory extends PlatformViewFactory { private boolean preserveContext; diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java index dd690c971b639..03fdbeee31ddd 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TestActivity.java @@ -4,6 +4,8 @@ package dev.flutter.scenarios; +import static io.flutter.Build.API_LEVELS; + import android.Manifest; import android.content.Context; import android.content.Intent; @@ -58,7 +60,7 @@ protected void onCreate(@Nullable Bundle savedInstanceState) { final Intent launchIntent = getIntent(); if ("com.google.intent.action.TEST_LOOP".equals(launchIntent.getAction())) { - if (Build.VERSION.SDK_INT > 22) { + if (Build.VERSION.SDK_INT > API_LEVELS.API_22) { requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1); } handler.postDelayed(resultsTask, 20000); diff --git a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TexturePlatformViewFactory.java b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TexturePlatformViewFactory.java index e79dd16ccb4c5..8664780374f96 100644 --- a/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TexturePlatformViewFactory.java +++ b/testing/scenario_app/android/app/src/main/java/dev/flutter/scenarios/TexturePlatformViewFactory.java @@ -4,6 +4,8 @@ package dev.flutter.scenarios; +import static io.flutter.Build.API_LEVELS; + import android.annotation.TargetApi; import android.content.Context; import android.graphics.Canvas; @@ -22,7 +24,7 @@ import io.flutter.plugin.platform.PlatformViewFactory; import java.nio.ByteBuffer; -@TargetApi(23) +@TargetApi(API_LEVELS.API_23) public final class TexturePlatformViewFactory extends PlatformViewFactory { TexturePlatformViewFactory() { super( diff --git a/tools/android_illegal_imports.py b/tools/android_illegal_imports.py index 9e875bbd17b1e..dfa77c35993ef 100644 --- a/tools/android_illegal_imports.py +++ b/tools/android_illegal_imports.py @@ -16,6 +16,8 @@ ANDROID_TRACE_CLASS = 'android.tracing.Trace' FLUTTER_TRACE_CLASS = 'io.flutter.util.TraceSection' +ANDROID_BUILD_VERSION_CODE_CLASS = 'VERSION_CODES' + def CheckBadFiles(bad_files, bad_class, good_class): if bad_files: @@ -42,10 +44,12 @@ def main(): bad_log_files = [] bad_trace_files = [] + bad_version_codes_files = [] for file in args.files: if (file.endswith(os.path.join('io', 'flutter', 'Log.java')) or - file.endswith(os.path.join('io', 'flutter', 'util', 'TraceSection.java'))): + file.endswith(os.path.join('io', 'flutter', 'util', 'TraceSection.java')) or + file.endswith(os.path.join('io', 'flutter', 'Build.java'))): continue with open(file) as f: contents = f.read() @@ -53,11 +57,23 @@ def main(): bad_log_files.append(file) if ANDROIDX_TRACE_CLASS in contents or ANDROID_TRACE_CLASS in contents: bad_trace_files.append(file) - - has_bad_files = CheckBadFiles(bad_log_files, ANDROID_LOG_CLASS, FLUTTER_LOG_CLASS) - has_bad_files = has_bad_files or CheckBadFiles( - bad_trace_files, 'android[x].tracing.Trace', FLUTTER_TRACE_CLASS - ) + if ANDROID_BUILD_VERSION_CODE_CLASS in contents: + bad_version_codes_files.append(file) + + # Flutter's Log class allows additional configuration around verbosity. + + # Flutter's tracing class makes sure we do not violate string lengths that + # cause crashes at runtime. + + # Flutter's Build.API_LEVELS class is clearer to read about which API version + # is used. + has_bad_files = CheckBadFiles(bad_log_files, ANDROID_LOG_CLASS, + FLUTTER_LOG_CLASS) or CheckBadFiles( + bad_trace_files, 'android[x].tracing.Trace', FLUTTER_TRACE_CLASS + ) or CheckBadFiles( + bad_version_codes_files, 'android.os.Build.VERSION_CODES', + 'io.flutter.Build.API_LEVELS' + ) if has_bad_files: return 1