diff options
| author | Philip Milne <pmilne@google.com> | 2012-05-12 09:34:25 -0700 |
|---|---|---|
| committer | Philip Milne <pmilne@google.com> | 2012-05-14 13:42:05 -0700 |
| commit | 0f57cea8989cc03bcae19b621096e50b035b7308 (patch) | |
| tree | da1d28bc436ca424baab6c2c95163bf52e857eda /core/java/android/widget/GridLayout.java | |
| parent | 6704c233390743890d23338a2329dcda5709b810 (diff) | |
Add validation code for GridLayout.LayoutParams
Bug 6404882.
The supplied code in this bug sets up a table with 2 columns and then
tries to add a component in column 5. Earlier attempts to fix this
by 'doing what the user meeant' had unwanted side-effects. This CL is
intended to defend against all ways to register invalid LayoutParams
and throw IllegalArgumentExcpetion when any column index falls outside the
range [0 .. N] where N is the number of columns. It also includes the
symmetrical check for rows.
Change-Id: I958a6d16035889cd954b78108773426e8b6b6d95
Diffstat (limited to 'core/java/android/widget/GridLayout.java')
| -rw-r--r-- | core/java/android/widget/GridLayout.java | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/core/java/android/widget/GridLayout.java b/core/java/android/widget/GridLayout.java index cb10d0a8fc28..60a1d15fc94f 100644 --- a/core/java/android/widget/GridLayout.java +++ b/core/java/android/widget/GridLayout.java @@ -581,7 +581,7 @@ public class GridLayout extends ViewGroup { } private int getDefaultMargin(View c, boolean isAtEdge, boolean horizontal, boolean leading) { - return /*isAtEdge ? DEFAULT_CONTAINER_MARGIN :*/ getDefaultMargin(c, horizontal, leading); + return isAtEdge ? DEFAULT_CONTAINER_MARGIN : getDefaultMargin(c, horizontal, leading); } private int getDefaultMargin(View c, LayoutParams p, boolean horizontal, boolean leading) { @@ -733,6 +733,11 @@ public class GridLayout extends ViewGroup { @Override protected void onSetLayoutParams(View child, ViewGroup.LayoutParams layoutParams) { super.onSetLayoutParams(child, layoutParams); + + if (!checkLayoutParams(layoutParams)) { + handleInvalidParams("supplied LayoutParams are of the wrong type"); + } + invalidateStructure(); } @@ -740,6 +745,43 @@ public class GridLayout extends ViewGroup { return (LayoutParams) c.getLayoutParams(); } + private static void handleInvalidParams(String msg) { + throw new IllegalArgumentException(msg + ". "); + } + + private void checkLayoutParams(LayoutParams lp, boolean horizontal) { + String groupName = horizontal ? "column" : "row"; + Spec spec = horizontal ? lp.columnSpec : lp.rowSpec; + Interval span = spec.span; + if (span.min != UNDEFINED && span.min < 0) { + handleInvalidParams(groupName + " indices must be positive"); + } + Axis axis = horizontal ? horizontalAxis : verticalAxis; + int count = axis.definedCount; + if (count != UNDEFINED) { + if (span.max > count) { + handleInvalidParams(groupName + + " indices (start + span) mustn't exceed the " + groupName + " count"); + } + if (span.size() > count) { + handleInvalidParams(groupName + " span mustn't exceed the " + groupName + " count"); + } + } + } + + @Override + protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { + if (!(p instanceof LayoutParams)) { + return false; + } + LayoutParams lp = (LayoutParams) p; + + checkLayoutParams(lp, true); + checkLayoutParams(lp, false); + + return true; + } + @Override protected LayoutParams generateDefaultLayoutParams() { return new LayoutParams(); @@ -1143,6 +1185,7 @@ public class GridLayout extends ViewGroup { Interval span = spec.span; result = max(result, span.min); result = max(result, span.max); + result = max(result, span.size()); } return result == -1 ? UNDEFINED : result; } @@ -1159,6 +1202,11 @@ public class GridLayout extends ViewGroup { } public void setCount(int count) { + if (count != UNDEFINED && count < getMaxIndex()) { + handleInvalidParams((horizontal ? "column" : "row") + + "Count must be greater than or equal to the maximum of all grid indices " + + "(and spans) defined in the LayoutParams of each child"); + } this.definedCount = count; } @@ -1478,20 +1526,6 @@ public class GridLayout extends ViewGroup { This is a special case of the Linear Programming problem that is, in turn, equivalent to the single-source shortest paths problem on a digraph, for which the O(n^2) Bellman-Ford algorithm the most commonly used general solution. - - Other algorithms are faster in the case where no arcs have negative weights - but allowing negative weights turns out to be the same as accommodating maximum - size requirements as well as minimum ones. - - Bellman-Ford works by iteratively 'relaxing' constraints over all nodes (an O(N) - process) and performing this step N times. Proof of correctness hinges on the - fact that there can be no negative weight chains of length > N - unless a - 'negative weight loop' exists. The algorithm catches this case in a final - checking phase that reports failure. - - By topologically sorting the nodes and checking this condition at each step - typical layout problems complete after the first iteration and the algorithm - completes in O(N) steps with very low constants. */ private void solve(Arc[] arcs, int[] locations) { String axisName = horizontal ? "horizontal" : "vertical"; |
