Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 36f6205

Browse files
authored
Bump minSdk to 19 for Android tests (#47686)
The latest Robolectric version, 4.11.x, removed the support for SDKs < 19 by following AndroidX strategy. Also following flutter/buildroot#750, and removing obsolete SDK checking in code to pass android_lint checking after bumping minSdk to 19 for testing target. [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 1ca461b commit 36f6205

18 files changed

+88
-212
lines changed

shell/platform/android/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
-->
66
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.flutter.app" android:versionCode="1" android:versionName="0.0.1">
77

8-
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="34" />
8+
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="34" />
99
<uses-permission android:name="android.permission.INTERNET" />
1010
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1111
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />

shell/platform/android/io/flutter/embedding/android/AndroidTouchProcessor.java

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -198,9 +198,7 @@ public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transfor
198198
public boolean onGenericMotionEvent(@NonNull MotionEvent event, @NonNull Context context) {
199199
// Method isFromSource is only available in API 18+ (Jelly Bean MR2)
200200
// Mouse hover support is not implemented for API < 18.
201-
boolean isPointerEvent =
202-
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
203-
&& event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
201+
boolean isPointerEvent = event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
204202
boolean isMovementEvent =
205203
(event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE
206204
|| event.getActionMasked() == MotionEvent.ACTION_SCROLL);

shell/platform/android/io/flutter/embedding/android/FlutterFragment.java

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
import android.content.ComponentCallbacks2;
99
import android.content.Context;
1010
import android.content.Intent;
11-
import android.os.Build;
1211
import android.os.Bundle;
1312
import android.view.LayoutInflater;
1413
import android.view.View;
@@ -172,16 +171,14 @@ public class FlutterFragment extends Fragment
172171

173172
@RequiresApi(18)
174173
private final OnWindowFocusChangeListener onWindowFocusChangeListener =
175-
Build.VERSION.SDK_INT >= 18
176-
? new OnWindowFocusChangeListener() {
177-
@Override
178-
public void onWindowFocusChanged(boolean hasFocus) {
179-
if (stillAttachedForEvent("onWindowFocusChanged")) {
180-
delegate.onWindowFocusChanged(hasFocus);
181-
}
182-
}
174+
new OnWindowFocusChangeListener() {
175+
@Override
176+
public void onWindowFocusChanged(boolean hasFocus) {
177+
if (stillAttachedForEvent("onWindowFocusChanged")) {
178+
delegate.onWindowFocusChanged(hasFocus);
183179
}
184-
: null;
180+
}
181+
};
185182

186183
/**
187184
* Creates a {@code FlutterFragment} with a default configuration.
@@ -1128,20 +1125,16 @@ public void onStop() {
11281125
@Override
11291126
public void onViewCreated(View view, Bundle savedInstanceState) {
11301127
super.onViewCreated(view, savedInstanceState);
1131-
if (Build.VERSION.SDK_INT >= 18) {
1132-
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
1133-
}
1128+
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
11341129
}
11351130

11361131
@Override
11371132
public void onDestroyView() {
11381133
super.onDestroyView();
1139-
if (Build.VERSION.SDK_INT >= 18) {
1140-
// onWindowFocusChangeListener is API 18+ only.
1141-
requireView()
1142-
.getViewTreeObserver()
1143-
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
1144-
}
1134+
// onWindowFocusChangeListener is API 18+ only.
1135+
requireView()
1136+
.getViewTreeObserver()
1137+
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
11451138
if (stillAttachedForEvent("onDestroyView")) {
11461139
delegate.onDestroyView();
11471140
}

shell/platform/android/io/flutter/embedding/android/FlutterImageView.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
* an {@link android.media.Image} and renders it to the {@link android.graphics.Canvas} in {@code
4040
* onDraw}.
4141
*/
42-
@TargetApi(19)
4342
public class FlutterImageView extends View implements RenderSurface {
4443
private static final String TAG = "FlutterImageView";
4544

@@ -99,7 +98,6 @@ private static void logW(String format, Object... args) {
9998
Log.w(TAG, String.format(Locale.US, format, args));
10099
}
101100

102-
@TargetApi(19)
103101
@SuppressLint("WrongConstant") // RGBA_8888 is a valid constant.
104102
@NonNull
105103
private static ImageReader createImageReader(int width, int height) {
@@ -194,7 +192,6 @@ public void resume() {
194192
* Acquires the next image to be drawn to the {@link android.graphics.Canvas}. Returns true if
195193
* there's an image available in the queue.
196194
*/
197-
@TargetApi(19)
198195
public boolean acquireLatestImage() {
199196
if (!isAttachedToFlutterRenderer) {
200197
return false;

shell/platform/android/io/flutter/embedding/android/FlutterView.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,6 @@ public FlutterView(@NonNull Context context, @NonNull FlutterTextureView flutter
290290
* <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
291291
* compatible with {@link PlatformViewsController}.
292292
*/
293-
@TargetApi(19)
294293
public FlutterView(@NonNull Context context, @NonNull FlutterImageView flutterImageView) {
295294
this(context, null, flutterImageView);
296295
}
@@ -357,7 +356,6 @@ private FlutterView(
357356
init();
358357
}
359358

360-
@TargetApi(19)
361359
private FlutterView(
362360
@NonNull Context context,
363361
@Nullable AttributeSet attrs,

shell/platform/android/io/flutter/embedding/engine/loader/FlutterLoader.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import android.os.Looper;
1717
import android.os.SystemClock;
1818
import android.util.DisplayMetrics;
19-
import android.view.WindowManager;
2019
import androidx.annotation.NonNull;
2120
import androidx.annotation.Nullable;
2221
import io.flutter.BuildConfig;
@@ -170,17 +169,9 @@ public void startInitialization(@NonNull Context applicationContext, @NonNull Se
170169
flutterApplicationInfo = ApplicationInfoLoader.load(appContext);
171170

172171
VsyncWaiter waiter;
173-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 /* 17 */) {
174-
final DisplayManager dm =
175-
(DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);
176-
waiter = VsyncWaiter.getInstance(dm, flutterJNI);
177-
} else {
178-
float fps =
179-
((WindowManager) appContext.getSystemService(Context.WINDOW_SERVICE))
180-
.getDefaultDisplay()
181-
.getRefreshRate();
182-
waiter = VsyncWaiter.getInstance(fps, flutterJNI);
183-
}
172+
final DisplayManager dm =
173+
(DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);
174+
waiter = VsyncWaiter.getInstance(dm, flutterJNI);
184175
waiter.init();
185176

186177
// Use a background thread for initialization tasks that require disk access.

shell/platform/android/io/flutter/embedding/engine/mutatorsstack/FlutterMutatorView.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static android.view.View.OnFocusChangeListener;
44

55
import android.annotation.SuppressLint;
6-
import android.annotation.TargetApi;
76
import android.content.Context;
87
import android.graphics.Canvas;
98
import android.graphics.Matrix;
@@ -23,7 +22,6 @@
2322
* A view that applies the {@link io.flutter.embedding.engine.mutatorsstack.FlutterMutatorsStack} to
2423
* its children.
2524
*/
26-
@TargetApi(19)
2725
public class FlutterMutatorView extends FrameLayout {
2826
private FlutterMutatorsStack mutatorsStack;
2927
private float screenDensity;

shell/platform/android/io/flutter/embedding/engine/renderer/FlutterRenderer.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,6 @@ public long id() {
355355
}
356356

357357
@Override
358-
@TargetApi(19)
359358
public void release() {
360359
if (released) {
361360
return;
@@ -369,7 +368,6 @@ public void release() {
369368
}
370369

371370
@Override
372-
@TargetApi(19)
373371
public void pushImage(Image image) {
374372
if (released) {
375373
return;
@@ -433,7 +431,6 @@ public Image acquireLatestImage() {
433431
}
434432

435433
@Override
436-
@TargetApi(19)
437434
protected void finalize() throws Throwable {
438435
try {
439436
if (released) {

shell/platform/android/io/flutter/plugin/localization/LocalizationPlugin.java

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import android.annotation.SuppressLint;
88
import android.content.Context;
99
import android.content.res.Configuration;
10-
import android.content.res.Resources;
1110
import android.os.Build;
1211
import android.os.LocaleList;
1312
import androidx.annotation.NonNull;
@@ -40,18 +39,9 @@ public String getStringResource(@NonNull String key, @Nullable String localeStri
4039
Locale locale = localeFromString(localeString);
4140

4241
// setLocale and createConfigurationContext is only available on API >= 17
43-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
44-
Configuration config = new Configuration(context.getResources().getConfiguration());
45-
config.setLocale(locale);
46-
localContext = context.createConfigurationContext(config);
47-
} else {
48-
// In API < 17, we have to update the locale in Configuration.
49-
Resources resources = context.getResources();
50-
Configuration config = resources.getConfiguration();
51-
savedLocale = config.locale;
52-
config.locale = locale;
53-
resources.updateConfiguration(config, null);
54-
}
42+
Configuration config = new Configuration(context.getResources().getConfiguration());
43+
config.setLocale(locale);
44+
localContext = context.createConfigurationContext(config);
5545
}
5646

5747
String packageName = context.getPackageName();
@@ -61,14 +51,6 @@ public String getStringResource(@NonNull String key, @Nullable String localeStri
6151
stringToReturn = localContext.getResources().getString(resId);
6252
}
6353

64-
// In API < 17, we had to restore the original locale after using.
65-
if (localeString != null && Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
66-
Resources resources = context.getResources();
67-
Configuration config = resources.getConfiguration();
68-
config.locale = savedLocale;
69-
resources.updateConfiguration(config, null);
70-
}
71-
7254
return stringToReturn;
7355
}
7456
};

shell/platform/android/io/flutter/plugin/platform/PlatformPlugin.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,7 @@ private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode sys
282282
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
283283
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
284284
| View.SYSTEM_UI_FLAG_FULLSCREEN;
285-
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE
286-
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
285+
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE) {
287286
// IMMERSIVE
288287
// Available starting at 19
289288
// Should not show overlays, swipe from edges to reveal overlays, needs onChange callback
@@ -298,8 +297,7 @@ private void setSystemChromeEnabledSystemUIMode(PlatformChannel.SystemUiMode sys
298297
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
299298
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
300299
| View.SYSTEM_UI_FLAG_FULLSCREEN;
301-
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY
302-
&& Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
300+
} else if (systemUiMode == PlatformChannel.SystemUiMode.IMMERSIVE_STICKY) {
303301
// STICKY IMMERSIVE
304302
// Available starting at 19
305303
// Should not show overlays, swipe from edges to reveal overlays. The app will also receive
@@ -346,7 +344,7 @@ private void setSystemChromeEnabledSystemUIOverlays(
346344
// The SYSTEM_UI_FLAG_IMMERSIVE_STICKY flag was introduced in API 19, so we
347345
// apply it
348346
// if desired, and if the current Android version is 19 or greater.
349-
if (overlaysToShow.size() == 0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
347+
if (overlaysToShow.size() == 0) {
350348
enabledOverlays |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
351349
}
352350

shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ public class PlatformViewsController implements PlatformViewsAccessibilityDelega
152152
private final PlatformViewsChannel.PlatformViewsHandler channelHandler =
153153
new PlatformViewsChannel.PlatformViewsHandler() {
154154

155-
@TargetApi(19)
156155
@Override
157156
// TODO(egarciad): Remove the need for this.
158157
// https://github.com/flutter/flutter/issues/96679
@@ -415,7 +414,6 @@ public void onTouch(@NonNull PlatformViewsChannel.PlatformViewTouch touch) {
415414
view.dispatchTouchEvent(event);
416415
}
417416

418-
@TargetApi(17)
419417
@Override
420418
public void setDirection(int viewId, int direction) {
421419
if (!validateDirection(direction)) {
@@ -500,7 +498,6 @@ private void ensureValidRequest(
500498

501499
// Creates a platform view based on `request`, performs configuration that's common to
502500
// all display modes, and adds it to `platformViews`.
503-
@TargetApi(19)
504501
@VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
505502
public PlatformView createPlatformView(
506503
@NonNull PlatformViewsChannel.PlatformViewCreationRequest request, boolean wrapContext) {
@@ -1084,7 +1081,6 @@ private void initializeRootImageViewIfNeeded() {
10841081
* testing.
10851082
*/
10861083
@VisibleForTesting
1087-
@TargetApi(Build.VERSION_CODES.KITKAT)
10881084
void initializePlatformViewIfNeeded(int viewId) {
10891085
final PlatformView platformView = platformViews.get(viewId);
10901086
if (platformView == null) {
@@ -1296,7 +1292,6 @@ private void finishFrame(boolean isFrameRenderedUsingImageReaders) {
12961292
* for public use, and is only visible for testing.
12971293
*/
12981294
@VisibleForTesting
1299-
@TargetApi(19)
13001295
@NonNull
13011296
public FlutterOverlaySurface createOverlaySurface(@NonNull PlatformOverlayView imageView) {
13021297
final int id = nextOverlayLayerId++;
@@ -1311,7 +1306,6 @@ public FlutterOverlaySurface createOverlaySurface(@NonNull PlatformOverlayView i
13111306
*
13121307
* <p>This member is not intended for public use, and is only visible for testing.
13131308
*/
1314-
@TargetApi(19)
13151309
@NonNull
13161310
public FlutterOverlaySurface createOverlaySurface() {
13171311
// Overlay surfaces have the same size as the background surface.

shell/platform/android/io/flutter/plugin/platform/SingleViewPresentation.java

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@
77
import static android.content.Context.WINDOW_SERVICE;
88
import static android.view.View.OnFocusChangeListener;
99

10-
import android.annotation.TargetApi;
1110
import android.app.AlertDialog;
1211
import android.app.Presentation;
1312
import android.content.Context;
1413
import android.content.ContextWrapper;
1514
import android.content.MutableContextWrapper;
1615
import android.graphics.Rect;
1716
import android.graphics.drawable.ColorDrawable;
18-
import android.os.Build;
1917
import android.os.Bundle;
2018
import android.view.Display;
2119
import android.view.Gravity;
@@ -51,7 +49,6 @@
5149
* EmbeddedView
5250
*/
5351
@Keep
54-
@TargetApi(Build.VERSION_CODES.KITKAT)
5552
class SingleViewPresentation extends Presentation {
5653
private static final String TAG = "PlatformViewsController";
5754

@@ -123,9 +120,7 @@ public SingleViewPresentation(
123120
.setFlags(
124121
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
125122
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE);
126-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
127-
getWindow().setType(WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
128-
}
123+
getWindow().setType(WindowManager.LayoutParams.TYPE_PRIVATE_PRESENTATION);
129124
}
130125

131126
/**

shell/platform/android/io/flutter/util/ViewUtils.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import android.app.Activity;
88
import android.content.Context;
99
import android.content.ContextWrapper;
10-
import android.os.Build;
1110
import android.view.View;
1211
import android.view.ViewGroup;
1312
import androidx.annotation.NonNull;
@@ -68,10 +67,7 @@ public static Activity getActivity(@Nullable Context context) {
6867
* @return the view id.
6968
*/
7069
public static int generateViewId(int fallbackId) {
71-
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
72-
return View.generateViewId();
73-
}
74-
return fallbackId;
70+
return View.generateViewId();
7571
}
7672

7773
/**

0 commit comments

Comments
 (0)