Skip to content

Commit c9381fb

Browse files
authored
Revert "Bump everything to Android 21" (flutter#51056)
Reverts flutter#51032 Probably causing some of the failures in flutter/flutter#144326 @johnmccutchan fyi
1 parent ce88fbc commit c9381fb

File tree

45 files changed

+670
-196
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+670
-196
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="21" android:targetSdkVersion="34" />
8+
<uses-sdk android:minSdkVersion="16" 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/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ android {
2323
compileSdkVersion 34
2424

2525
defaultConfig {
26-
minSdkVersion 21
26+
minSdkVersion 19
2727
}
2828

2929
sourceSets {

shell/platform/android/io/flutter/app/FlutterActivityDelegate.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import android.content.res.Configuration;
1818
import android.content.res.Resources.NotFoundException;
1919
import android.graphics.drawable.Drawable;
20+
import android.os.Build;
2021
import android.os.Bundle;
2122
import android.util.TypedValue;
2223
import android.view.View;
@@ -136,10 +137,12 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
136137

137138
@Override
138139
public void onCreate(Bundle savedInstanceState) {
139-
Window window = activity.getWindow();
140-
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
141-
window.setStatusBarColor(0x40000000);
142-
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
140+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
141+
Window window = activity.getWindow();
142+
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
143+
window.setStatusBarColor(0x40000000);
144+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
145+
}
143146

144147
String[] args = getArgsFromIntent(activity.getIntent());
145148
FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), args);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transfor
204204
public boolean onGenericMotionEvent(@NonNull MotionEvent event, @NonNull Context context) {
205205
// Method isFromSource is only available in API 18+ (Jelly Bean MR2)
206206
// Mouse hover support is not implemented for API < 18.
207-
boolean isPointerEvent = event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
207+
boolean isPointerEvent =
208+
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
209+
&& event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
208210
boolean isMovementEvent =
209211
(event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE
210212
|| event.getActionMasked() == MotionEvent.ACTION_SCROLL);

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

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import io.flutter.embedding.engine.plugins.activity.ActivityControlSurface;
5050
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
5151
import io.flutter.plugin.platform.PlatformPlugin;
52+
import io.flutter.util.ViewUtils;
5253
import java.util.ArrayList;
5354
import java.util.List;
5455

@@ -215,7 +216,7 @@ public class FlutterActivity extends Activity
215216
* <p>This ID can be used to lookup {@code FlutterView} in the Android view hierarchy. For more,
216217
* see {@link android.view.View#findViewById}.
217218
*/
218-
public static final int FLUTTER_VIEW_ID = View.generateViewId();
219+
public static final int FLUTTER_VIEW_ID = ViewUtils.generateViewId(0xF1F2);
219220

220221
/**
221222
* Creates an {@link Intent} that launches a {@code FlutterActivity}, which creates a {@link
@@ -772,10 +773,12 @@ private View createFlutterView() {
772773
}
773774

774775
private void configureStatusBarForFullscreenFlutterExperience() {
775-
Window window = getWindow();
776-
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
777-
window.setStatusBarColor(0x40000000);
778-
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
776+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
777+
Window window = getWindow();
778+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
779+
window.setStatusBarColor(0x40000000);
780+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
781+
}
779782
}
780783

781784
@Override

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

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import android.content.ComponentCallbacks2;
99
import android.content.Context;
1010
import android.content.Intent;
11+
import android.os.Build;
1112
import android.os.Bundle;
1213
import android.view.LayoutInflater;
1314
import android.view.View;
@@ -16,6 +17,7 @@
1617
import androidx.activity.OnBackPressedCallback;
1718
import androidx.annotation.NonNull;
1819
import androidx.annotation.Nullable;
20+
import androidx.annotation.RequiresApi;
1921
import androidx.annotation.VisibleForTesting;
2022
import androidx.fragment.app.Fragment;
2123
import androidx.fragment.app.FragmentActivity;
@@ -25,6 +27,7 @@
2527
import io.flutter.embedding.engine.FlutterShellArgs;
2628
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
2729
import io.flutter.plugin.platform.PlatformPlugin;
30+
import io.flutter.util.ViewUtils;
2831
import java.util.ArrayList;
2932
import java.util.List;
3033

@@ -104,7 +107,7 @@ public class FlutterFragment extends Fragment
104107
* <p>This ID can be used to lookup {@code FlutterView} in the Android view hierarchy. For more,
105108
* see {@link android.view.View#findViewById}.
106109
*/
107-
public static final int FLUTTER_VIEW_ID = View.generateViewId();
110+
public static final int FLUTTER_VIEW_ID = ViewUtils.generateViewId(0xF1F2);
108111

109112
private static final String TAG = "FlutterFragment";
110113

@@ -167,15 +170,18 @@ public class FlutterFragment extends Fragment
167170
protected static final String ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED =
168171
"should_automatically_handle_on_back_pressed";
169172

173+
@RequiresApi(18)
170174
private final OnWindowFocusChangeListener onWindowFocusChangeListener =
171-
new OnWindowFocusChangeListener() {
172-
@Override
173-
public void onWindowFocusChanged(boolean hasFocus) {
174-
if (stillAttachedForEvent("onWindowFocusChanged")) {
175-
delegate.onWindowFocusChanged(hasFocus);
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+
}
176183
}
177-
}
178-
};
184+
: null;
179185

180186
/**
181187
* Creates a {@code FlutterFragment} with a default configuration.
@@ -1122,15 +1128,20 @@ public void onStop() {
11221128
@Override
11231129
public void onViewCreated(View view, Bundle savedInstanceState) {
11241130
super.onViewCreated(view, savedInstanceState);
1125-
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
1131+
if (Build.VERSION.SDK_INT >= 18) {
1132+
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
1133+
}
11261134
}
11271135

11281136
@Override
11291137
public void onDestroyView() {
11301138
super.onDestroyView();
1131-
requireView()
1132-
.getViewTreeObserver()
1133-
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
1139+
if (Build.VERSION.SDK_INT >= 18) {
1140+
// onWindowFocusChangeListener is API 18+ only.
1141+
requireView()
1142+
.getViewTreeObserver()
1143+
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
1144+
}
11341145
if (stillAttachedForEvent("onDestroyView")) {
11351146
delegate.onDestroyView();
11361147
}

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import android.content.pm.PackageManager;
2828
import android.graphics.Color;
2929
import android.graphics.drawable.ColorDrawable;
30+
import android.os.Build;
3031
import android.os.Bundle;
3132
import android.view.View;
3233
import android.view.ViewGroup;
@@ -44,6 +45,7 @@
4445
import io.flutter.embedding.engine.FlutterShellArgs;
4546
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
4647
import io.flutter.plugin.platform.PlatformPlugin;
48+
import io.flutter.util.ViewUtils;
4749
import java.util.ArrayList;
4850
import java.util.List;
4951

@@ -65,7 +67,8 @@ public class FlutterFragmentActivity extends FragmentActivity
6567
// FlutterFragment management.
6668
private static final String TAG_FLUTTER_FRAGMENT = "flutter_fragment";
6769
// TODO(mattcarroll): replace ID with R.id when build system supports R.java
68-
public static final int FRAGMENT_CONTAINER_ID = View.generateViewId();
70+
public static final int FRAGMENT_CONTAINER_ID =
71+
ViewUtils.generateViewId(609893468); // random number
6972

7073
/**
7174
* Creates an {@link Intent} that launches a {@code FlutterFragmentActivity}, which executes a
@@ -597,10 +600,12 @@ protected FlutterFragment createFlutterFragment() {
597600
}
598601

599602
private void configureStatusBarForFullscreenFlutterExperience() {
600-
Window window = getWindow();
601-
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
602-
window.setStatusBarColor(0x40000000);
603-
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
603+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
604+
Window window = getWindow();
605+
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
606+
window.setStatusBarColor(0x40000000);
607+
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
608+
}
604609
}
605610

606611
@Override

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

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

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

102+
@TargetApi(19)
101103
@SuppressLint("WrongConstant") // RGBA_8888 is a valid constant.
102104
@NonNull
103105
private static ImageReader createImageReader(int width, int height) {
@@ -185,6 +187,7 @@ public void resume() {
185187
* Acquires the next image to be drawn to the {@link android.graphics.Canvas}. Returns true if
186188
* there's an image available in the queue.
187189
*/
190+
@TargetApi(19)
188191
public boolean acquireLatestImage() {
189192
if (!isAttachedToFlutterRenderer) {
190193
return false;

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

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,7 @@ 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)
293294
public FlutterView(@NonNull Context context, @NonNull FlutterImageView flutterImageView) {
294295
this(context, null, flutterImageView);
295296
}
@@ -356,6 +357,7 @@ private FlutterView(
356357
init();
357358
}
358359

360+
@TargetApi(19)
359361
private FlutterView(
360362
@NonNull Context context,
361363
@Nullable AttributeSet attrs,
@@ -641,7 +643,8 @@ else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
641643
//
642644
// This method is replaced by Android API 30 (R/11) getInsets() method which can take the
643645
// android.view.WindowInsets.Type.ime() flag to find the keyboard inset.
644-
646+
@TargetApi(20)
647+
@RequiresApi(20)
645648
private int guessBottomKeyboardInset(WindowInsets insets) {
646649
int screenHeight = getRootView().getHeight();
647650
// Magic number due to this being a heuristic. This should be replaced, but we have not
@@ -667,7 +670,8 @@ private int guessBottomKeyboardInset(WindowInsets insets) {
667670
* wider than expected padding when the status and navigation bars are hidden.
668671
*/
669672
@Override
670-
673+
@TargetApi(20)
674+
@RequiresApi(20)
671675
// The annotations to suppress "InlinedApi" and "NewApi" lints prevent lint warnings
672676
// caused by usage of Android Q APIs. These calls are safe because they are
673677
// guarded.
@@ -798,6 +802,53 @@ navigationBarVisible && guessBottomKeyboardInset(insets) == 0
798802
sendViewportMetricsToFlutter();
799803
return newInsets;
800804
}
805+
806+
/**
807+
* Invoked when Android's desired window insets change, i.e., padding.
808+
*
809+
* <p>{@code fitSystemWindows} is an earlier version of {@link
810+
* #onApplyWindowInsets(WindowInsets)}. See that method for more details about how window insets
811+
* relate to Flutter.
812+
*/
813+
@Override
814+
@SuppressWarnings("deprecation")
815+
protected boolean fitSystemWindows(@NonNull Rect insets) {
816+
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
817+
// Status bar, left/right system insets partially obscure content (padding).
818+
viewportMetrics.viewPaddingTop = insets.top;
819+
viewportMetrics.viewPaddingRight = insets.right;
820+
viewportMetrics.viewPaddingBottom = 0;
821+
viewportMetrics.viewPaddingLeft = insets.left;
822+
823+
// Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
824+
viewportMetrics.viewInsetTop = 0;
825+
viewportMetrics.viewInsetRight = 0;
826+
viewportMetrics.viewInsetBottom = insets.bottom;
827+
viewportMetrics.viewInsetLeft = 0;
828+
829+
Log.v(
830+
TAG,
831+
"Updating window insets (fitSystemWindows()):\n"
832+
+ "Status bar insets: Top: "
833+
+ viewportMetrics.viewPaddingTop
834+
+ ", Left: "
835+
+ viewportMetrics.viewPaddingLeft
836+
+ ", Right: "
837+
+ viewportMetrics.viewPaddingRight
838+
+ "\n"
839+
+ "Keyboard insets: Bottom: "
840+
+ viewportMetrics.viewInsetBottom
841+
+ ", Left: "
842+
+ viewportMetrics.viewInsetLeft
843+
+ ", Right: "
844+
+ viewportMetrics.viewInsetRight);
845+
846+
sendViewportMetricsToFlutter();
847+
return true;
848+
} else {
849+
return super.fitSystemWindows(insets);
850+
}
851+
}
801852
// ------- End: Process View configuration that Flutter cares about. --------
802853

803854
// -------- Start: Process UI I/O that Flutter cares about. -------
@@ -879,7 +930,14 @@ public boolean onTouchEvent(@NonNull MotionEvent event) {
879930
return super.onTouchEvent(event);
880931
}
881932

882-
requestUnbufferedDispatch(event);
933+
// TODO(abarth): This version check might not be effective in some
934+
// versions of Android that statically compile code and will be upset
935+
// at the lack of |requestUnbufferedDispatch|. Instead, we should factor
936+
// version-dependent code into separate classes for each supported
937+
// version and dispatch dynamically.
938+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
939+
requestUnbufferedDispatch(event);
940+
}
883941

884942
return androidTouchProcessor.onTouchEvent(event);
885943
}

shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1297,17 +1297,22 @@ public String[] computePlatformResolvedLocale(@NonNull String[] strings) {
12971297
String countryCode = strings[i + 1];
12981298
String scriptCode = strings[i + 2];
12991299
// Convert to Locales via LocaleBuilder if available (API 21+) to include scriptCode.
1300-
Locale.Builder localeBuilder = new Locale.Builder();
1301-
if (!languageCode.isEmpty()) {
1302-
localeBuilder.setLanguage(languageCode);
1303-
}
1304-
if (!countryCode.isEmpty()) {
1305-
localeBuilder.setRegion(countryCode);
1306-
}
1307-
if (!scriptCode.isEmpty()) {
1308-
localeBuilder.setScript(scriptCode);
1300+
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
1301+
Locale.Builder localeBuilder = new Locale.Builder();
1302+
if (!languageCode.isEmpty()) {
1303+
localeBuilder.setLanguage(languageCode);
1304+
}
1305+
if (!countryCode.isEmpty()) {
1306+
localeBuilder.setRegion(countryCode);
1307+
}
1308+
if (!scriptCode.isEmpty()) {
1309+
localeBuilder.setScript(scriptCode);
1310+
}
1311+
supportedLocales.add(localeBuilder.build());
1312+
} else {
1313+
// Pre-API 21, we fall back on scriptCode-less locales.
1314+
supportedLocales.add(new Locale(languageCode, countryCode));
13091315
}
1310-
supportedLocales.add(localeBuilder.build());
13111316
}
13121317

13131318
Locale result = localizationPlugin.resolveNativeLocale(supportedLocales);
@@ -1318,7 +1323,11 @@ public String[] computePlatformResolvedLocale(@NonNull String[] strings) {
13181323
String[] output = new String[localeDataLength];
13191324
output[0] = result.getLanguage();
13201325
output[1] = result.getCountry();
1321-
output[2] = result.getScript();
1326+
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
1327+
output[2] = result.getScript();
1328+
} else {
1329+
output[2] = "";
1330+
}
13221331
return output;
13231332
}
13241333

0 commit comments

Comments
 (0)