summaryrefslogtreecommitdiff
path: root/core/java/android/widget/GridLayout.java
diff options
context:
space:
mode:
authorPhilip Milne <pmilne@google.com>2012-05-12 09:34:25 -0700
committerPhilip Milne <pmilne@google.com>2012-05-14 13:42:05 -0700
commit0f57cea8989cc03bcae19b621096e50b035b7308 (patch)
treeda1d28bc436ca424baab6c2c95163bf52e857eda /core/java/android/widget/GridLayout.java
parent6704c233390743890d23338a2329dcda5709b810 (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.java64
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";