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-team-archive/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

Lines changed: 88 additions & 212 deletions

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

0 commit comments

Comments
 (0)