From 2dd20a61e959f9a0acb0639664e063101b6e3bac Mon Sep 17 00:00:00 2001 From: Yigit Boyar Date: Mon, 1 Aug 2016 17:42:28 -0700 Subject: [PATCH] Target API check for margin params fix Prior to N, our widgets were not converting MarginLayoutParams properly between ViewGroups. The fix intrudced some issues in older apps as the broken conversion code would hide developer errors. This CL guards the change with a target API check so that we don't affect older apps. Bug: 30378230 Change-Id: I215281d261b553c3b4cedcd29ea0a861df809471 --- core/java/android/view/View.java | 15 +++++++++++++++ core/java/android/widget/FrameLayout.java | 13 +++++++------ core/java/android/widget/GridLayout.java | 13 +++++++------ core/java/android/widget/LinearLayout.java | 13 +++++++------ core/java/android/widget/RelativeLayout.java | 13 +++++++------ 5 files changed, 43 insertions(+), 24 deletions(-) diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java index 69f1747719008..0cdf5e115e3a0 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -820,6 +820,17 @@ public class View implements Drawable.Callback, KeyEvent.Callback, */ static boolean sTextureViewIgnoresDrawableSetters = false; + /** + * Prior to N, some ViewGroups would not convert LayoutParams properly even though both extend + * MarginLayoutParams. For instance, converting LinearLayout.LayoutParams to + * RelativeLayout.LayoutParams would lose margin information. This is fixed on N but target API + * check is implemented for backwards compatibility. + * + * {@hide} + */ + protected static boolean sPreserveMarginParamsInLayoutParamConversion; + + /** * This view does not want keystrokes. Use with TAKES_FOCUS_MASK when * calling setFlags. @@ -4052,6 +4063,10 @@ public class View implements Drawable.Callback, KeyEvent.Callback, // On N+, we throw, but that breaks compatibility with apps that use these methods. sTextureViewIgnoresDrawableSetters = targetSdkVersion <= M; + // Prior to N, we would drop margins in LayoutParam conversions. The fix triggers bugs + // in apps so we target check it to avoid breaking existing apps. + sPreserveMarginParamsInLayoutParamConversion = targetSdkVersion >= N; + sCompatibilityDone = true; } } diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java index 029313c539389..b8c74d88b5807 100644 --- a/core/java/android/widget/FrameLayout.java +++ b/core/java/android/widget/FrameLayout.java @@ -382,13 +382,14 @@ public class FrameLayout extends ViewGroup { @Override protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp instanceof LayoutParams) { - return new LayoutParams((LayoutParams) lp); - } else if (lp instanceof MarginLayoutParams) { - return new LayoutParams((MarginLayoutParams) lp); - } else { - return new LayoutParams(lp); + if (sPreserveMarginParamsInLayoutParamConversion) { + if (lp instanceof LayoutParams) { + return new LayoutParams((LayoutParams) lp); + } else if (lp instanceof MarginLayoutParams) { + return new LayoutParams((MarginLayoutParams) lp); + } } + return new LayoutParams(lp); } @Override diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index 726586ee8d5f3..af2852cde22a1 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -868,13 +868,14 @@ public class GridLayout extends ViewGroup { @Override protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp instanceof LayoutParams) { - return new LayoutParams((LayoutParams) lp); - } else if (lp instanceof MarginLayoutParams) { - return new LayoutParams((MarginLayoutParams) lp); - } else { - return new LayoutParams(lp); + if (sPreserveMarginParamsInLayoutParamConversion) { + if (lp instanceof LayoutParams) { + return new LayoutParams((LayoutParams) lp); + } else if (lp instanceof MarginLayoutParams) { + return new LayoutParams((MarginLayoutParams) lp); + } } + return new LayoutParams(lp); } // Draw grid diff --git a/core/java/android/widget/LinearLayout.java b/core/java/android/widget/LinearLayout.java index 38d7cd4acaf66..f897372c1f019 100644 --- a/core/java/android/widget/LinearLayout.java +++ b/core/java/android/widget/LinearLayout.java @@ -1844,13 +1844,14 @@ public class LinearLayout extends ViewGroup { @Override protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp instanceof LayoutParams) { - return new LayoutParams((LayoutParams) lp); - } else if (lp instanceof MarginLayoutParams) { - return new LayoutParams((MarginLayoutParams) lp); - } else { - return new LayoutParams(lp); + if (sPreserveMarginParamsInLayoutParamConversion) { + if (lp instanceof LayoutParams) { + return new LayoutParams((LayoutParams) lp); + } else if (lp instanceof MarginLayoutParams) { + return new LayoutParams((MarginLayoutParams) lp); + } } + return new LayoutParams(lp); } diff --git a/core/java/android/widget/RelativeLayout.java b/core/java/android/widget/RelativeLayout.java index 0136542ef4ac8..a189d3c0cc912 100644 --- a/core/java/android/widget/RelativeLayout.java +++ b/core/java/android/widget/RelativeLayout.java @@ -1104,13 +1104,14 @@ public class RelativeLayout extends ViewGroup { @Override protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) { - if (lp instanceof LayoutParams) { - return new LayoutParams((LayoutParams) lp); - } else if (lp instanceof MarginLayoutParams) { - return new LayoutParams((MarginLayoutParams) lp); - } else { - return new LayoutParams(lp); + if (sPreserveMarginParamsInLayoutParamConversion) { + if (lp instanceof LayoutParams) { + return new LayoutParams((LayoutParams) lp); + } else if (lp instanceof MarginLayoutParams) { + return new LayoutParams((MarginLayoutParams) lp); + } } + return new LayoutParams(lp); } /** @hide */