Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "Bump everything to Android 21" #51056

Merged
merged 1 commit into from
Feb 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion shell/platform/android/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="io.flutter.app" android:versionCode="1" android:versionName="0.0.1">

<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="34" />
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="34" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
Expand Down
2 changes: 1 addition & 1 deletion shell/platform/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ android {
compileSdkVersion 34

defaultConfig {
minSdkVersion 21
minSdkVersion 19
}

sourceSets {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import android.content.res.Configuration;
import android.content.res.Resources.NotFoundException;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.util.TypedValue;
import android.view.View;
Expand Down Expand Up @@ -136,10 +137,12 @@ public boolean onActivityResult(int requestCode, int resultCode, Intent data) {

@Override
public void onCreate(Bundle savedInstanceState) {
Window window = activity.getWindow();
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = activity.getWindow();
window.addFlags(LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
}

String[] args = getArgsFromIntent(activity.getIntent());
FlutterMain.ensureInitializationComplete(activity.getApplicationContext(), args);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,9 @@ public boolean onTouchEvent(@NonNull MotionEvent event, @NonNull Matrix transfor
public boolean onGenericMotionEvent(@NonNull MotionEvent event, @NonNull Context context) {
// Method isFromSource is only available in API 18+ (Jelly Bean MR2)
// Mouse hover support is not implemented for API < 18.
boolean isPointerEvent = event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
boolean isPointerEvent =
Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2
&& event.isFromSource(InputDevice.SOURCE_CLASS_POINTER);
boolean isMovementEvent =
(event.getActionMasked() == MotionEvent.ACTION_HOVER_MOVE
|| event.getActionMasked() == MotionEvent.ACTION_SCROLL);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
import io.flutter.embedding.engine.plugins.activity.ActivityControlSurface;
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.util.ViewUtils;
import java.util.ArrayList;
import java.util.List;

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

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

private void configureStatusBarForFullscreenFlutterExperience() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import android.content.ComponentCallbacks2;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
Expand All @@ -16,6 +17,7 @@
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.RequiresApi;
import androidx.annotation.VisibleForTesting;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
Expand All @@ -25,6 +27,7 @@
import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.renderer.FlutterUiDisplayListener;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.util.ViewUtils;
import java.util.ArrayList;
import java.util.List;

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

private static final String TAG = "FlutterFragment";

Expand Down Expand Up @@ -167,15 +170,18 @@ public class FlutterFragment extends Fragment
protected static final String ARG_SHOULD_AUTOMATICALLY_HANDLE_ON_BACK_PRESSED =
"should_automatically_handle_on_back_pressed";

@RequiresApi(18)
private final OnWindowFocusChangeListener onWindowFocusChangeListener =
new OnWindowFocusChangeListener() {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (stillAttachedForEvent("onWindowFocusChanged")) {
delegate.onWindowFocusChanged(hasFocus);
Build.VERSION.SDK_INT >= 18
? new OnWindowFocusChangeListener() {
@Override
public void onWindowFocusChanged(boolean hasFocus) {
if (stillAttachedForEvent("onWindowFocusChanged")) {
delegate.onWindowFocusChanged(hasFocus);
}
}
}
}
};
: null;

/**
* Creates a {@code FlutterFragment} with a default configuration.
Expand Down Expand Up @@ -1122,15 +1128,20 @@ public void onStop() {
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
if (Build.VERSION.SDK_INT >= 18) {
view.getViewTreeObserver().addOnWindowFocusChangeListener(onWindowFocusChangeListener);
}
}

@Override
public void onDestroyView() {
super.onDestroyView();
requireView()
.getViewTreeObserver()
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
if (Build.VERSION.SDK_INT >= 18) {
// onWindowFocusChangeListener is API 18+ only.
requireView()
.getViewTreeObserver()
.removeOnWindowFocusChangeListener(onWindowFocusChangeListener);
}
if (stillAttachedForEvent("onDestroyView")) {
delegate.onDestroyView();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -44,6 +45,7 @@
import io.flutter.embedding.engine.FlutterShellArgs;
import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
import io.flutter.plugin.platform.PlatformPlugin;
import io.flutter.util.ViewUtils;
import java.util.ArrayList;
import java.util.List;

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

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

private void configureStatusBarForFullscreenFlutterExperience() {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS);
window.setStatusBarColor(0x40000000);
window.getDecorView().setSystemUiVisibility(PlatformPlugin.DEFAULT_SYSTEM_UI);
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
* an {@link android.media.Image} and renders it to the {@link android.graphics.Canvas} in {@code
* onDraw}.
*/
@TargetApi(19)
public class FlutterImageView extends View implements RenderSurface {
private static final String TAG = "FlutterImageView";

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

@TargetApi(19)
@SuppressLint("WrongConstant") // RGBA_8888 is a valid constant.
@NonNull
private static ImageReader createImageReader(int width, int height) {
Expand Down Expand Up @@ -185,6 +187,7 @@ public void resume() {
* Acquires the next image to be drawn to the {@link android.graphics.Canvas}. Returns true if
* there's an image available in the queue.
*/
@TargetApi(19)
public boolean acquireLatestImage() {
if (!isAttachedToFlutterRenderer) {
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,7 @@ public FlutterView(@NonNull Context context, @NonNull FlutterTextureView flutter
* <p>{@code FlutterView} requires an {@code Activity} instead of a generic {@code Context} to be
* compatible with {@link PlatformViewsController}.
*/
@TargetApi(19)
public FlutterView(@NonNull Context context, @NonNull FlutterImageView flutterImageView) {
this(context, null, flutterImageView);
}
Expand Down Expand Up @@ -356,6 +357,7 @@ private FlutterView(
init();
}

@TargetApi(19)
private FlutterView(
@NonNull Context context,
@Nullable AttributeSet attrs,
Expand Down Expand Up @@ -641,7 +643,8 @@ else if (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180) {
//
// This method is replaced by Android API 30 (R/11) getInsets() method which can take the
// android.view.WindowInsets.Type.ime() flag to find the keyboard inset.

@TargetApi(20)
@RequiresApi(20)
private int guessBottomKeyboardInset(WindowInsets insets) {
int screenHeight = getRootView().getHeight();
// Magic number due to this being a heuristic. This should be replaced, but we have not
Expand All @@ -667,7 +670,8 @@ private int guessBottomKeyboardInset(WindowInsets insets) {
* wider than expected padding when the status and navigation bars are hidden.
*/
@Override

@TargetApi(20)
@RequiresApi(20)
// The annotations to suppress "InlinedApi" and "NewApi" lints prevent lint warnings
// caused by usage of Android Q APIs. These calls are safe because they are
// guarded.
Expand Down Expand Up @@ -798,6 +802,53 @@ navigationBarVisible && guessBottomKeyboardInset(insets) == 0
sendViewportMetricsToFlutter();
return newInsets;
}

/**
* Invoked when Android's desired window insets change, i.e., padding.
*
* <p>{@code fitSystemWindows} is an earlier version of {@link
* #onApplyWindowInsets(WindowInsets)}. See that method for more details about how window insets
* relate to Flutter.
*/
@Override
@SuppressWarnings("deprecation")
protected boolean fitSystemWindows(@NonNull Rect insets) {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.KITKAT) {
// Status bar, left/right system insets partially obscure content (padding).
viewportMetrics.viewPaddingTop = insets.top;
viewportMetrics.viewPaddingRight = insets.right;
viewportMetrics.viewPaddingBottom = 0;
viewportMetrics.viewPaddingLeft = insets.left;

// Bottom system inset (keyboard) should adjust scrollable bottom edge (inset).
viewportMetrics.viewInsetTop = 0;
viewportMetrics.viewInsetRight = 0;
viewportMetrics.viewInsetBottom = insets.bottom;
viewportMetrics.viewInsetLeft = 0;

Log.v(
TAG,
"Updating window insets (fitSystemWindows()):\n"
+ "Status bar insets: Top: "
+ viewportMetrics.viewPaddingTop
+ ", Left: "
+ viewportMetrics.viewPaddingLeft
+ ", Right: "
+ viewportMetrics.viewPaddingRight
+ "\n"
+ "Keyboard insets: Bottom: "
+ viewportMetrics.viewInsetBottom
+ ", Left: "
+ viewportMetrics.viewInsetLeft
+ ", Right: "
+ viewportMetrics.viewInsetRight);

sendViewportMetricsToFlutter();
return true;
} else {
return super.fitSystemWindows(insets);
}
}
// ------- End: Process View configuration that Flutter cares about. --------

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

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

return androidTouchProcessor.onTouchEvent(event);
}
Expand Down
31 changes: 20 additions & 11 deletions shell/platform/android/io/flutter/embedding/engine/FlutterJNI.java
Original file line number Diff line number Diff line change
Expand Up @@ -1297,17 +1297,22 @@ public String[] computePlatformResolvedLocale(@NonNull String[] strings) {
String countryCode = strings[i + 1];
String scriptCode = strings[i + 2];
// Convert to Locales via LocaleBuilder if available (API 21+) to include scriptCode.
Locale.Builder localeBuilder = new Locale.Builder();
if (!languageCode.isEmpty()) {
localeBuilder.setLanguage(languageCode);
}
if (!countryCode.isEmpty()) {
localeBuilder.setRegion(countryCode);
}
if (!scriptCode.isEmpty()) {
localeBuilder.setScript(scriptCode);
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
Locale.Builder localeBuilder = new Locale.Builder();
if (!languageCode.isEmpty()) {
localeBuilder.setLanguage(languageCode);
}
if (!countryCode.isEmpty()) {
localeBuilder.setRegion(countryCode);
}
if (!scriptCode.isEmpty()) {
localeBuilder.setScript(scriptCode);
}
supportedLocales.add(localeBuilder.build());
} else {
// Pre-API 21, we fall back on scriptCode-less locales.
supportedLocales.add(new Locale(languageCode, countryCode));
}
supportedLocales.add(localeBuilder.build());
}

Locale result = localizationPlugin.resolveNativeLocale(supportedLocales);
Expand All @@ -1318,7 +1323,11 @@ public String[] computePlatformResolvedLocale(@NonNull String[] strings) {
String[] output = new String[localeDataLength];
output[0] = result.getLanguage();
output[1] = result.getCountry();
output[2] = result.getScript();
if (Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
output[2] = result.getScript();
} else {
output[2] = "";
}
return output;
}

Expand Down
Loading