diff --git a/api/current.txt b/api/current.txt
index 89fcfc3..dc44a16 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -31064,12 +31064,26 @@
     method public static android.util.Range<T> create(T, T);
     method public T getLower();
     method public T getUpper();
+    method public boolean inRange(T);
   }
 
-  public final class Rational {
+  public final class Rational extends java.lang.Number implements java.lang.Comparable {
     ctor public Rational(int, int);
+    method public int compareTo(android.util.Rational);
+    method public double doubleValue();
+    method public float floatValue();
     method public int getDenominator();
     method public int getNumerator();
+    method public int intValue();
+    method public boolean isFinite();
+    method public boolean isInfinite();
+    method public boolean isNaN();
+    method public boolean isZero();
+    method public long longValue();
+    field public static final android.util.Rational NEGATIVE_INFINITY;
+    field public static final android.util.Rational NaN;
+    field public static final android.util.Rational POSITIVE_INFINITY;
+    field public static final android.util.Rational ZERO;
   }
 
   public final class Size {
diff --git a/core/java/android/util/Range.java b/core/java/android/util/Range.java
index d7e8cf0..3907e77 100644
--- a/core/java/android/util/Range.java
+++ b/core/java/android/util/Range.java
@@ -97,6 +97,27 @@
     }
 
     /**
+     * Checks if the {@code value} is within the bounds of this range.
+     *
+     * <p>A value is considered to be within this range if it's {@code >=} then
+     * the lower endpoint <i>and</i> {@code <=} to the upper endpoint (using the {@link Comparable}
+     * interface.</p>
+     *
+     * @param value a non-{@code null} {@code T} reference
+     * @return {@code true} if the value is within this inclusive range, {@code false} otherwise
+     *
+     * @throws NullPointerException if {@code value} was {@code null}
+     */
+    public boolean inRange(T value) {
+        checkNotNull(value, "value must not be null");
+
+        boolean gteLower = value.compareTo(mLower) >= 0;
+        boolean lteUpper  = value.compareTo(mUpper) <= 0;
+
+        return gteLower && lteUpper;
+    }
+
+    /**
      * Compare two ranges for equality.
      *
      * <p>A range is considered equal if and only if both the lower and upper endpoints
@@ -105,16 +126,13 @@
      * @return {@code true} if the ranges are equal, {@code false} otherwise
      */
     @Override
-    public boolean equals(final Object obj) {
+    public boolean equals(Object obj) {
         if (obj == null) {
             return false;
-        }
-        if (this == obj) {
+        } else if (this == obj) {
             return true;
-        }
-        if (obj instanceof Range) {
+        } else if (obj instanceof Range) {
             @SuppressWarnings("rawtypes")
-            final
             Range other = (Range) obj;
             return mLower.equals(other.mLower) && mUpper.equals(other.mUpper);
         }
diff --git a/core/java/android/util/Rational.java b/core/java/android/util/Rational.java
index 8d4c67f..9952859 100644
--- a/core/java/android/util/Rational.java
+++ b/core/java/android/util/Rational.java
@@ -15,29 +15,88 @@
  */
 package android.util;
 
+import static com.android.internal.util.Preconditions.*;
+
+import java.io.IOException;
+import java.io.InvalidObjectException;
+
 /**
  * <p>An immutable data type representation a rational number.</p>
  *
  * <p>Contains a pair of {@code int}s representing the numerator and denominator of a
  * Rational number. </p>
  */
-public final class Rational {
+public final class Rational extends Number implements Comparable<Rational> {
+    /**
+     * Constant for the <em>Not-a-Number (NaN)</em> value of the {@code Rational} type.
+     *
+     * <p>A {@code NaN} value is considered to be equal to itself (that is {@code NaN.equals(NaN)}
+     * will return {@code true}; it is always greater than any non-{@code NaN} value (that is
+     * {@code NaN.compareTo(notNaN)} will return a number greater than {@code 0}).</p>
+     *
+     * <p>Equivalent to constructing a new rational with both the numerator and denominator
+     * equal to {@code 0}.</p>
+     */
+    public static final Rational NaN = new Rational(0, 0);
+
+    /**
+     * Constant for the positive infinity value of the {@code Rational} type.
+     *
+     * <p>Equivalent to constructing a new rational with a positive numerator and a denominator
+     * equal to {@code 0}.</p>
+     */
+    public static final Rational POSITIVE_INFINITY = new Rational(1, 0);
+
+    /**
+     * Constant for the negative infinity value of the {@code Rational} type.
+     *
+     * <p>Equivalent to constructing a new rational with a negative numerator and a denominator
+     * equal to {@code 0}.</p>
+     */
+    public static final Rational NEGATIVE_INFINITY = new Rational(-1, 0);
+
+    /**
+     * Constant for the zero value of the {@code Rational} type.
+     *
+     * <p>Equivalent to constructing a new rational with a numerator equal to {@code 0} and
+     * any non-zero denominator.</p>
+     */
+    public static final Rational ZERO = new Rational(0, 1);
+
+    /**
+     * Unique version number per class to be compliant with {@link java.io.Serializable}.
+     *
+     * <p>Increment each time the fields change in any way.</p>
+     */
+    private static final long serialVersionUID = 1L;
+
+    /*
+     * Do not change the order of these fields or add new instance fields to maintain the
+     * Serializable compatibility across API revisions.
+     */
     private final int mNumerator;
     private final int mDenominator;
 
     /**
-     * <p>Create a Rational with a given numerator and denominator.</p>
+     * <p>Create a {@code Rational} with a given numerator and denominator.</p>
      *
      * <p>The signs of the numerator and the denominator may be flipped such that the denominator
-     * is always positive.</p>
+     * is always positive. Both the numerator and denominator will be converted to their reduced
+     * forms (see {@link #equals} for more details).</p>
      *
-     * <p>A rational value with a 0-denominator may be constructed, but will have similar semantics
-     * as float {@code NaN} and {@code INF} values. For {@code NaN},
-     * both {@link #getNumerator} and {@link #getDenominator} functions will return 0. For
-     * positive or negative {@code INF}, only the {@link #getDenominator} will return 0.</p>
+     * <p>For example,
+     * <ul>
+     * <li>a rational of {@code 2/4} will be reduced to {@code 1/2}.
+     * <li>a rational of {@code 1/-1} will be flipped to {@code -1/1}
+     * <li>a rational of {@code 5/0} will be reduced to {@code 1/0}
+     * <li>a rational of {@code 0/5} will be reduced to {@code 0/1}
+     * </ul>
+     * </p>
      *
      * @param numerator the numerator of the rational
      * @param denominator the denominator of the rational
+     *
+     * @see #equals
      */
     public Rational(int numerator, int denominator) {
 
@@ -46,32 +105,100 @@
             denominator = -denominator;
         }
 
-        mNumerator = numerator;
-        mDenominator = denominator;
+        // Convert to reduced form
+        if (denominator == 0 && numerator > 0) {
+            mNumerator = 1; // +Inf
+            mDenominator = 0;
+        } else if (denominator == 0 && numerator < 0) {
+            mNumerator = -1; // -Inf
+            mDenominator = 0;
+        } else if (denominator == 0 && numerator == 0) {
+            mNumerator = 0; // NaN
+            mDenominator = 0;
+        } else if (numerator == 0) {
+            mNumerator = 0;
+            mDenominator = 1;
+        } else {
+            int gcd = gcd(numerator, denominator);
+
+            mNumerator = numerator / gcd;
+            mDenominator = denominator / gcd;
+        }
     }
 
     /**
      * Gets the numerator of the rational.
+     *
+     * <p>The numerator will always return {@code 1} if this rational represents
+     * infinity (that is, the denominator is {@code 0}).</p>
      */
     public int getNumerator() {
-        if (mDenominator == 0) {
-            return 0;
-        }
         return mNumerator;
     }
 
     /**
      * Gets the denominator of the rational
+     *
+     * <p>The denominator may return {@code 0}, in which case the rational may represent
+     * positive infinity (if the numerator was positive), negative infinity (if the numerator
+     * was negative), or {@code NaN} (if the numerator was {@code 0}).</p>
+     *
+     * <p>The denominator will always return {@code 1} if the numerator is {@code 0}.
      */
     public int getDenominator() {
         return mDenominator;
     }
 
-    private boolean isNaN() {
+    /**
+     * Indicates whether this rational is a <em>Not-a-Number (NaN)</em> value.
+     *
+     * <p>A {@code NaN} value occurs when both the numerator and the denominator are {@code 0}.</p>
+     *
+     * @return {@code true} if this rational is a <em>Not-a-Number (NaN)</em> value;
+     *         {@code false} if this is a (potentially infinite) number value
+     */
+    public boolean isNaN() {
         return mDenominator == 0 && mNumerator == 0;
     }
 
-    private boolean isInf() {
+    /**
+     * Indicates whether this rational represents an infinite value.
+     *
+     * <p>An infinite value occurs when the denominator is {@code 0} (but the numerator is not).</p>
+     *
+     * @return {@code true} if this rational is a (positive or negative) infinite value;
+     *         {@code false} if this is a finite number value (or {@code NaN})
+     */
+    public boolean isInfinite() {
+        return mNumerator != 0 && mDenominator == 0;
+    }
+
+    /**
+     * Indicates whether this rational represents a finite value.
+     *
+     * <p>A finite value occurs when the denominator is not {@code 0}; in other words
+     * the rational is neither infinity or {@code NaN}.</p>
+     *
+     * @return {@code true} if this rational is a (positive or negative) infinite value;
+     *         {@code false} if this is a finite number value (or {@code NaN})
+     */
+    public boolean isFinite() {
+        return mDenominator != 0;
+    }
+
+    /**
+     * Indicates whether this rational represents a zero value.
+     *
+     * <p>A zero value is a {@link #isFinite finite} rational with a numerator of {@code 0}.</p>
+     *
+     * @return {@code true} if this rational is finite zero value;
+     *         {@code false} otherwise
+     */
+    public boolean isZero() {
+        return isFinite() && mNumerator == 0;
+    }
+
+    private boolean isPosInf() {
         return mDenominator == 0 && mNumerator > 0;
     }
 
@@ -82,12 +209,12 @@
     /**
      * <p>Compare this Rational to another object and see if they are equal.</p>
      *
-     * <p>A Rational object can only be equal to another Rational object (comparing against any other
-     * type will return false).</p>
+     * <p>A Rational object can only be equal to another Rational object (comparing against any
+     * other type will return {@code false}).</p>
      *
      * <p>A Rational object is considered equal to another Rational object if and only if one of
-     * the following holds</p>:
-     * <ul><li>Both are NaN</li>
+     * the following holds:</p>
+     * <ul><li>Both are {@code NaN}</li>
      *     <li>Both are infinities of the same sign</li>
      *     <li>Both have the same numerator and denominator in their reduced form</li>
      * </ul>
@@ -96,12 +223,12 @@
      * denominator by their greatest common divisor.</p>
      *
      * <pre>{@code
-     *      (new Rational(1, 2)).equals(new Rational(1, 2)) == true   // trivially true
-     *      (new Rational(2, 3)).equals(new Rational(1, 2)) == false  // trivially false
-     *      (new Rational(1, 2)).equals(new Rational(2, 4)) == true   // true after reduction
-     *      (new Rational(0, 0)).equals(new Rational(0, 0)) == true   // NaN.equals(NaN)
-     *      (new Rational(1, 0)).equals(new Rational(5, 0)) == true   // both are +infinity
-     *      (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
+     * (new Rational(1, 2)).equals(new Rational(1, 2)) == true   // trivially true
+     * (new Rational(2, 3)).equals(new Rational(1, 2)) == false  // trivially false
+     * (new Rational(1, 2)).equals(new Rational(2, 4)) == true   // true after reduction
+     * (new Rational(0, 0)).equals(new Rational(0, 0)) == true   // NaN.equals(NaN)
+     * (new Rational(1, 0)).equals(new Rational(5, 0)) == true   // both are +infinity
+     * (new Rational(1, 0)).equals(new Rational(-1, 0)) == false // +infinity != -infinity
      * }</pre>
      *
      * @param obj a reference to another object
@@ -110,41 +237,31 @@
      */
     @Override
     public boolean equals(Object obj) {
-        if (obj == null) {
-            return false;
-        } else if (obj instanceof Rational) {
-            Rational other = (Rational) obj;
-            if (mDenominator == 0 || other.mDenominator == 0) {
-                if (isNaN() && other.isNaN()) {
-                    return true;
-                } else if (isInf() && other.isInf() || isNegInf() && other.isNegInf()) {
-                    return true;
-                } else {
-                    return false;
-                }
-            } else if (mNumerator == other.mNumerator && mDenominator == other.mDenominator) {
-                return true;
-            } else {
-                int thisGcd = gcd();
-                int otherGcd = other.gcd();
-
-                int thisNumerator = mNumerator / thisGcd;
-                int thisDenominator = mDenominator / thisGcd;
-
-                int otherNumerator = other.mNumerator / otherGcd;
-                int otherDenominator = other.mDenominator / otherGcd;
-
-                return (thisNumerator == otherNumerator && thisDenominator == otherDenominator);
-            }
-        }
-        return false;
+        return obj instanceof Rational && equals((Rational) obj);
     }
 
+    private boolean equals(Rational other) {
+        return (mNumerator == other.mNumerator && mDenominator == other.mDenominator);
+    }
+
+    /**
+     * Return a string representation of this rational, e.g. {@code "1/2"}.
+     *
+     * <p>The following rules of conversion apply:
+     * <ul>
+     * <li>{@code NaN} values will return {@code "NaN"}
+     * <li>Positive infinity values will return {@code "Infinity"}
+     * <li>Negative infinity values will return {@code "-Infinity"}
+     * <li>All other values will return {@code "numerator/denominator"} where {@code numerator}
+     * and {@code denominator} are substituted with the appropriate numerator and denominator
+     * values.
+     * </ul></p>
+     */
     @Override
     public String toString() {
         if (isNaN()) {
             return "NaN";
-        } else if (isInf()) {
+        } else if (isPosInf()) {
             return "Infinity";
         } else if (isNegInf()) {
             return "-Infinity";
@@ -160,7 +277,8 @@
      * @hide
      */
     public float toFloat() {
-        return (float) mNumerator / (float) mDenominator;
+        // TODO: remove this duplicate function (used in CTS and the shim)
+        return floatValue();
     }
 
     /**
@@ -177,20 +295,24 @@
     /**
      * Calculates the greatest common divisor using Euclid's algorithm.
      *
+     * <p><em>Visible for testing only.</em></p>
+     *
+     * @param numerator the numerator in a fraction
+     * @param denominator the denominator in a fraction
+     *
      * @return An int value representing the gcd. Always positive.
      * @hide
      */
-    public int gcd() {
-        /**
+    public static int gcd(int numerator, int denominator) {
+        /*
          * Non-recursive implementation of Euclid's algorithm:
          *
          *  gcd(a, 0) := a
          *  gcd(a, b) := gcd(b, a mod b)
          *
          */
-
-        int a = mNumerator;
-        int b = mDenominator;
+        int a = numerator;
+        int b = denominator;
 
         while (b != 0) {
             int oldB = b;
@@ -201,4 +323,221 @@
 
         return Math.abs(a);
     }
+
+    /**
+     * Returns the value of the specified number as a {@code double}.
+     *
+     * <p>The {@code double} is calculated by converting both the numerator and denominator
+     * to a {@code double}; then returning the result of dividing the numerator by the
+     * denominator.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code double}.
+     */
+    @Override
+    public double doubleValue() {
+        double num = mNumerator;
+        double den = mDenominator;
+
+        return num / den;
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code float}.
+     *
+     * <p>The {@code float} is calculated by converting both the numerator and denominator
+     * to a {@code float}; then returning the result of dividing the numerator by the
+     * denominator.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code float}.
+     */
+    @Override
+    public float floatValue() {
+        float num = mNumerator;
+        float den = mDenominator;
+
+        return num / den;
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code int}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to an {@code int} value
+     * by dividing the numerator by the denominator; conversion for non-finite values happens
+     * identically to casting a floating point value to an {@code int}, in particular:
+     *
+     * <p>
+     * <ul>
+     * <li>Positive infinity saturates to the largest maximum integer
+     * {@link Integer#MAX_VALUE}</li>
+     * <li>Negative infinity saturates to the smallest maximum integer
+     * {@link Integer#MIN_VALUE}</li>
+     * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li>
+     * </ul>
+     * </p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code int}.
+     */
+    @Override
+    public int intValue() {
+        // Mimic float to int conversion rules from JLS 5.1.3
+
+        if (isPosInf()) {
+            return Integer.MAX_VALUE;
+        } else if (isNegInf()) {
+            return Integer.MIN_VALUE;
+        } else if (isNaN()) {
+            return 0;
+        } else { // finite
+            return mNumerator / mDenominator;
+        }
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code long}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to an {@code long} value
+     * by dividing the numerator by the denominator; conversion for non-finite values happens
+     * identically to casting a floating point value to a {@code long}, in particular:
+     *
+     * <p>
+     * <ul>
+     * <li>Positive infinity saturates to the largest maximum long
+     * {@link Long#MAX_VALUE}</li>
+     * <li>Negative infinity saturates to the smallest maximum long
+     * {@link Long#MIN_VALUE}</li>
+     * <li><em>Not-A-Number (NaN)</em> returns {@code 0}.</li>
+     * </ul>
+     * </p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code long}.
+     */
+    @Override
+    public long longValue() {
+        // Mimic float to long conversion rules from JLS 5.1.3
+
+        if (isPosInf()) {
+            return Long.MAX_VALUE;
+        } else if (isNegInf()) {
+            return Long.MIN_VALUE;
+        } else if (isNaN()) {
+            return 0;
+        } else { // finite
+            return mNumerator / mDenominator;
+        }
+    }
+
+    /**
+     * Returns the value of the specified number as a {@code short}.
+     *
+     * <p>{@link #isInfinite Finite} rationals are converted to a {@code short} value
+     * identically to {@link #intValue}; the {@code int} result is then truncated to a
+     * {@code short} before returning the value.</p>
+     *
+     * @return the divided value of the numerator and denominator as a {@code short}.
+     */
+    @Override
+    public short shortValue() {
+        return (short) intValue();
+    }
+
+    /**
+     * Compare this rational to the specified rational to determine their natural order.
+     *
+     * <p>{@link #NaN} is considered to be equal to itself and greater than all other
+     * {@code Rational} values. Otherwise, if the objects are not {@link #equals equal}, then
+     * the following rules apply:</p>
+     *
+     * <ul>
+     * <li>Positive infinity is greater than any other finite number (or negative infinity)
+     * <li>Negative infinity is less than any other finite number (or positive infinity)
+     * <li>The finite number represented by this rational is checked numerically
+     * against the other finite number by converting both rationals to a common denominator multiple
+     * and comparing their numerators.
+     * </ul>
+     *
+     * @param another the rational to be compared
+     *
+     * @return a negative integer, zero, or a positive integer as this object is less than,
+     *         equal to, or greater than the specified rational.
+     *
+     * @throws NullPointerException if {@code another} was {@code null}
+     */
+    @Override
+    public int compareTo(Rational another) {
+        checkNotNull(another, "another must not be null");
+
+        if (equals(another)) {
+            return 0;
+        } else if (isNaN()) { // NaN is greater than the other non-NaN value
+            return 1;
+        } else if (another.isNaN()) { // the other NaN is greater than this non-NaN value
+            return -1;
+        } else if (isPosInf() || another.isNegInf()) {
+            return 1; // positive infinity is greater than any non-NaN/non-posInf value
+        } else if (isNegInf() || another.isPosInf()) {
+            return -1; // negative infinity is less than any non-NaN/non-negInf value
+        }
+
+        // else both this and another are finite numbers
+
+        // make the denominators the same, then compare numerators
+        long thisNumerator = ((long)mNumerator) * another.mDenominator; // long to avoid overflow
+        long otherNumerator = ((long)another.mNumerator) * mDenominator; // long to avoid overflow
+
+        // avoid underflow from subtraction by doing comparisons
+        if (thisNumerator < otherNumerator) {
+            return -1;
+        } else if (thisNumerator > otherNumerator) {
+            return 1;
+        } else {
+            // This should be covered by #equals, but have this code path just in case
+            return 0;
+        }
+    }
+
+    /*
+     * Serializable implementation.
+     *
+     * The following methods are omitted:
+     * >> writeObject - the default is sufficient (field by field serialization)
+     * >> readObjectNoData - the default is sufficient (0s for both fields is a NaN)
+     */
+
+    /**
+     * writeObject with default serialized form - guards against
+     * deserializing non-reduced forms of the rational.
+     *
+     * @throws InvalidObjectException if the invariants were violated
+     */
+    private void readObject(java.io.ObjectInputStream in)
+            throws IOException, ClassNotFoundException {
+        in.defaultReadObject();
+
+        /*
+         * Guard against trying to deserialize illegal values (in this case, ones
+         * that don't have a standard reduced form).
+         *
+         * - Non-finite values must be one of [0, 1], [0, 0], [0, 1], [0, -1]
+         * - Finite values must always have their greatest common divisor as 1
+         */
+
+        if (mNumerator == 0) { // either zero or NaN
+            if (mDenominator == 1 || mDenominator == 0) {
+                return;
+            }
+            throw new InvalidObjectException(
+                    "Rational must be deserialized from a reduced form for zero values");
+        } else if (mDenominator == 0) { // either positive or negative infinity
+            if (mNumerator == 1 || mNumerator == -1) {
+                return;
+            }
+            throw new InvalidObjectException(
+                    "Rational must be deserialized from a reduced form for infinity values");
+        } else { // finite value
+            if (gcd(mNumerator, mDenominator) > 1) {
+                throw new InvalidObjectException(
+                    "Rational must be deserialized from a reduced form for finite values");
+            }
+        }
+    }
 }
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java
new file mode 100644
index 0000000..d90a4bc
--- /dev/null
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RangeTest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.mediaframeworktest.unit;
+
+import android.test.suitebuilder.annotation.SmallTest;
+import android.util.Range;
+import android.util.Rational;
+
+/**
+ * <pre>
+ * adb shell am instrument \
+ *      -e class 'com.android.mediaframeworktest.unit.RangeTest' \
+ *      -w com.android.mediaframeworktest/.MediaFrameworkUnitTestRunner
+ * </pre>
+ */
+public class RangeTest extends junit.framework.TestCase {
+
+    @SmallTest
+    public void testConstructor() {
+        // Trivial, same range
+        Range<Integer> intRange = new Range<Integer>(1, 1);
+
+        assertLower(intRange, 1);
+        assertUpper(intRange, 1);
+
+        // Different values in range
+        Range<Integer> intRange2 = new Range<Integer>(100, 200);
+        assertLower(intRange2, 100);
+        assertUpper(intRange2, 200);
+
+        Range<Float> floatRange = new Range<Float>(Float.NEGATIVE_INFINITY,
+                Float.POSITIVE_INFINITY);
+        assertLower(floatRange, Float.NEGATIVE_INFINITY);
+        assertUpper(floatRange, Float.POSITIVE_INFINITY);
+    }
+
+    @SmallTest
+    public void testIllegalValues() {
+        // Test NPEs
+        try {
+            new Range<Integer>(null, null);
+            fail("Expected exception to be thrown for (null, null)");
+        } catch (NullPointerException e) {
+            // OK: both args are null
+        }
+
+        try {
+            new Range<Integer>(null, 0);
+            fail("Expected exception to be thrown for (null, 0)");
+        } catch (NullPointerException e) {
+            // OK: left arg is null
+        }
+
+        try {
+            new Range<Integer>(0, null);
+            fail("Expected exception to be thrown for (0, null)");
+        } catch (NullPointerException e) {
+            // OK: right arg is null
+        }
+
+        // Test IAEs
+
+        try {
+            new Range<Integer>(50, -50);
+            fail("Expected exception to be thrown for (50, -50)");
+        } catch (IllegalArgumentException e) {
+            // OK: 50 > -50 so it fails
+        }
+
+        try {
+            new Range<Float>(0.0f, Float.NEGATIVE_INFINITY);
+            fail("Expected exception to be thrown for (0.0f, -Infinity)");
+        } catch (IllegalArgumentException e) {
+            // OK: 0.0f is > NEGATIVE_INFINITY, so it fails
+        }
+    }
+
+    @SmallTest
+    public void testEquals() {
+        Range<Float> oneHalf = Range.create(1.0f, 2.0f);
+        Range<Float> oneHalf2 = new Range<Float>(1.0f, 2.0f);
+        assertEquals(oneHalf, oneHalf2);
+        assertHashCodeEquals(oneHalf, oneHalf2);
+
+        Range<Float> twoThirds = new Range<Float>(2.0f, 3.0f);
+        Range<Float> twoThirds2 = Range.create(2.0f, 3.0f);
+        assertEquals(twoThirds, twoThirds2);
+        assertHashCodeEquals(twoThirds, twoThirds2);
+
+        Range<Rational> negativeOneTenthPositiveOneTenth =
+                new Range<Rational>(new Rational(-1, 10), new Rational(1, 10));
+        Range<Rational> negativeOneTenthPositiveOneTenth2 =
+                Range.create(new Rational(-1, 10), new Rational(1, 10));
+        assertEquals(negativeOneTenthPositiveOneTenth, negativeOneTenthPositiveOneTenth2);
+        assertHashCodeEquals(negativeOneTenthPositiveOneTenth, negativeOneTenthPositiveOneTenth2);
+    }
+
+    @SmallTest
+    public void testInRange() {
+        Range<Integer> hundredOneTwo = Range.create(100, 200);
+
+        assertInRange(hundredOneTwo, 100);
+        assertInRange(hundredOneTwo, 200);
+        assertInRange(hundredOneTwo, 150);
+        assertOutOfRange(hundredOneTwo, 99);
+        assertOutOfRange(hundredOneTwo, 201);
+        assertOutOfRange(hundredOneTwo, 100000);
+
+        Range<Float> infinities = Range.create(Float.NEGATIVE_INFINITY, Float.POSITIVE_INFINITY);
+
+        assertInRange(infinities, Float.NEGATIVE_INFINITY);
+        assertInRange(infinities, Float.POSITIVE_INFINITY);
+        assertInRange(infinities, 0.0f);
+        assertOutOfRange(infinities, Float.NaN);
+
+        Range<Rational> negativeOneTenthPositiveOneTenth =
+                new Range<Rational>(new Rational(-1, 10), new Rational(1, 10));
+        assertInRange(negativeOneTenthPositiveOneTenth, new Rational(-1, 10));
+        assertInRange(negativeOneTenthPositiveOneTenth, new Rational(1, 10));
+        assertInRange(negativeOneTenthPositiveOneTenth, Rational.ZERO);
+        assertOutOfRange(negativeOneTenthPositiveOneTenth, new Rational(-100, 1));
+        assertOutOfRange(negativeOneTenthPositiveOneTenth, new Rational(100, 1));
+    }
+
+    private static <T extends Comparable<? super T>> void assertInRange(Range<T> object, T needle) {
+        assertAction("in-range", object, needle, true, object.inRange(needle));
+    }
+
+    private static <T extends Comparable<? super T>> void assertOutOfRange(Range<T> object,
+            T needle) {
+        assertAction("out-of-range", object, needle, false, object.inRange(needle));
+    }
+
+    private static <T extends Comparable<? super T>> void assertUpper(Range<T> object, T expected) {
+        assertAction("upper", object, expected, object.getUpper());
+    }
+
+    private static <T extends Comparable<? super T>> void assertLower(Range<T> object, T expected) {
+        assertAction("lower", object, expected, object.getLower());
+    }
+
+    private static <T, T2> void assertAction(String action, T object, T2 expected,
+            T2 actual) {
+        assertEquals("Expected " + object + " " + action + " to be ",
+                expected, actual);
+    }
+
+    private static <T, T2> void assertAction(String action, T object, T2 needle, boolean expected,
+            boolean actual) {
+        String expectedMessage = expected ? action : ("not " + action);
+        assertEquals("Expected " + needle + " to be " + expectedMessage + " of " + object,
+                expected, actual);
+    }
+
+    private static <T extends Comparable<? super T>> void assertHashCodeEquals(
+            Range<T> left, Range<T> right) {
+        assertEquals("Left hash code for " + left +
+                " expected to be equal to right hash code for " + right,
+                left.hashCode(), right.hashCode());
+    }
+}
diff --git a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
index 18c0d3e..1bb7db9 100644
--- a/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
+++ b/media/tests/MediaFrameworkTest/src/com/android/mediaframeworktest/unit/RationalTest.java
@@ -19,6 +19,17 @@
 import android.test.suitebuilder.annotation.SmallTest;
 import android.util.Rational;
 
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InvalidObjectException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import java.lang.reflect.Field;
+
+import static android.util.Rational.*;
+
 /**
  * <pre>
  * adb shell am instrument \
@@ -27,6 +38,22 @@
  * </pre>
  */
 public class RationalTest extends junit.framework.TestCase {
+
+    /** (1,1) */
+    private static final Rational UNIT = new Rational(1, 1);
+
+    /**
+     * Test @hide greatest common divisior functionality that cannot be tested in CTS.
+     */
+    @SmallTest
+    public void testGcd() {
+        assertEquals(1, Rational.gcd(1, 2));
+        assertEquals(1, Rational.gcd(2, 3));
+        assertEquals(78, Rational.gcd(5*78, 7*78));
+        assertEquals(1, Rational.gcd(-1, 2));
+        assertEquals(1, Rational.gcd(-2, 3));
+    }
+
     @SmallTest
     public void testConstructor() {
 
@@ -52,12 +79,12 @@
 
         // Infinity.
         r = new Rational(1, 0);
-        assertEquals(0, r.getNumerator());
+        assertEquals(1, r.getNumerator());
         assertEquals(0, r.getDenominator());
 
         // Negative infinity.
         r = new Rational(-1, 0);
-        assertEquals(0, r.getNumerator());
+        assertEquals(-1, r.getNumerator());
         assertEquals(0, r.getDenominator());
 
         // NaN.
@@ -67,24 +94,6 @@
     }
 
     @SmallTest
-    public void testGcd() {
-        Rational r = new Rational(1, 2);
-        assertEquals(1, r.gcd());
-
-        Rational twoThirds = new Rational(2, 3);
-        assertEquals(1, twoThirds.gcd());
-
-        Rational moreComplicated2 = new Rational(5*78, 7*78);
-        assertEquals(78, moreComplicated2.gcd());
-
-        Rational oneHalf = new Rational(-1, 2);
-        assertEquals(1, oneHalf.gcd());
-
-        twoThirds = new Rational(-2, 3);
-        assertEquals(1, twoThirds.gcd());
-    }
-
-    @SmallTest
     public void testEquals() {
         Rational r = new Rational(1, 2);
         assertEquals(1, r.getNumerator());
@@ -118,7 +127,13 @@
         assertEquals(moreComplicated, moreComplicated2);
         assertEquals(moreComplicated2, moreComplicated);
 
-        Rational nan = new Rational(0, 0);
+        // Zero is always equal to itself
+        Rational zero2 = new Rational(0, 100);
+        assertEquals(ZERO, zero2);
+        assertEquals(zero2, ZERO);
+
+        // NaN is always equal to itself
+        Rational nan = NaN;
         Rational nan2 = new Rational(0, 0);
         assertTrue(nan.equals(nan));
         assertTrue(nan.equals(nan2));
@@ -127,9 +142,9 @@
         assertFalse(r.equals(nan));
 
         // Infinities of the same sign are equal.
-        Rational posInf = new Rational(1, 0);
+        Rational posInf = POSITIVE_INFINITY;
         Rational posInf2 = new Rational(2, 0);
-        Rational negInf = new Rational(-1, 0);
+        Rational negInf = NEGATIVE_INFINITY;
         Rational negInf2 = new Rational(-2, 0);
         assertEquals(posInf, posInf);
         assertEquals(negInf, negInf);
@@ -148,4 +163,349 @@
         assertFalse(nan.equals(posInf));
         assertFalse(nan.equals(negInf));
     }
+
+    @SmallTest
+    public void testReduction() {
+        Rational moreComplicated = new Rational(5 * 78, 7 * 78);
+        assertEquals(new Rational(5, 7), moreComplicated);
+        assertEquals(5, moreComplicated.getNumerator());
+        assertEquals(7, moreComplicated.getDenominator());
+
+        Rational posInf = new Rational(5, 0);
+        assertEquals(1, posInf.getNumerator());
+        assertEquals(0, posInf.getDenominator());
+        assertEquals(POSITIVE_INFINITY, posInf);
+
+        Rational negInf = new Rational(-100, 0);
+        assertEquals(-1, negInf.getNumerator());
+        assertEquals(0, negInf.getDenominator());
+        assertEquals(NEGATIVE_INFINITY, negInf);
+
+        Rational zero = new Rational(0, -100);
+        assertEquals(0, zero.getNumerator());
+        assertEquals(1, zero.getDenominator());
+        assertEquals(ZERO, zero);
+
+        Rational flipSigns = new Rational(1, -1);
+        assertEquals(-1, flipSigns.getNumerator());
+        assertEquals(1, flipSigns.getDenominator());
+
+        Rational flipAndReduce = new Rational(100, -200);
+        assertEquals(-1, flipAndReduce.getNumerator());
+        assertEquals(2, flipAndReduce.getDenominator());
+    }
+
+    @SmallTest
+    public void testCompareTo() {
+        // unit is equal to itself
+        assertCompareEquals(UNIT, new Rational(1, 1));
+
+        // NaN is greater than anything but NaN
+        assertCompareEquals(NaN, new Rational(0, 0));
+        assertGreaterThan(NaN, UNIT);
+        assertGreaterThan(NaN, POSITIVE_INFINITY);
+        assertGreaterThan(NaN, NEGATIVE_INFINITY);
+        assertGreaterThan(NaN, ZERO);
+
+        // Positive infinity is greater than any other non-NaN
+        assertCompareEquals(POSITIVE_INFINITY, new Rational(1, 0));
+        assertGreaterThan(POSITIVE_INFINITY, UNIT);
+        assertGreaterThan(POSITIVE_INFINITY, NEGATIVE_INFINITY);
+        assertGreaterThan(POSITIVE_INFINITY, ZERO);
+
+        // Negative infinity is smaller than any other non-NaN
+        assertCompareEquals(NEGATIVE_INFINITY, new Rational(-1, 0));
+        assertLessThan(NEGATIVE_INFINITY, UNIT);
+        assertLessThan(NEGATIVE_INFINITY, POSITIVE_INFINITY);
+        assertLessThan(NEGATIVE_INFINITY, ZERO);
+
+        // A finite number with the same denominator is trivially comparable
+        assertGreaterThan(new Rational(3, 100), new Rational(1, 100));
+        assertGreaterThan(new Rational(3, 100), ZERO);
+
+        // Compare finite numbers with different divisors
+        assertGreaterThan(new Rational(5, 25), new Rational(1, 10));
+        assertGreaterThan(new Rational(5, 25), ZERO);
+
+        // Compare finite numbers with different signs
+        assertGreaterThan(new Rational(5, 25), new Rational(-1, 10));
+        assertLessThan(new Rational(-5, 25), ZERO);
+    }
+
+    @SmallTest
+    public void testConvenienceMethods() {
+        // isFinite
+        assertFinite(ZERO, true);
+        assertFinite(NaN, false);
+        assertFinite(NEGATIVE_INFINITY, false);
+        assertFinite(POSITIVE_INFINITY, false);
+        assertFinite(UNIT, true);
+
+        // isInfinite
+        assertInfinite(ZERO, false);
+        assertInfinite(NaN, false);
+        assertInfinite(NEGATIVE_INFINITY, true);
+        assertInfinite(POSITIVE_INFINITY, true);
+        assertInfinite(UNIT, false);
+
+        // isNaN
+        assertNaN(ZERO, false);
+        assertNaN(NaN, true);
+        assertNaN(NEGATIVE_INFINITY, false);
+        assertNaN(POSITIVE_INFINITY, false);
+        assertNaN(UNIT, false);
+
+        // isZero
+        assertZero(ZERO, true);
+        assertZero(NaN, false);
+        assertZero(NEGATIVE_INFINITY, false);
+        assertZero(POSITIVE_INFINITY, false);
+        assertZero(UNIT, false);
+    }
+
+    @SmallTest
+    public void testValueConversions() {
+        // Unit, simple case
+        assertValueEquals(UNIT, 1.0f);
+        assertValueEquals(UNIT, 1.0);
+        assertValueEquals(UNIT, 1L);
+        assertValueEquals(UNIT, 1);
+        assertValueEquals(UNIT, (short)1);
+
+        // Zero, simple case
+        assertValueEquals(ZERO, 0.0f);
+        assertValueEquals(ZERO, 0.0);
+        assertValueEquals(ZERO, 0L);
+        assertValueEquals(ZERO, 0);
+        assertValueEquals(ZERO, (short)0);
+
+        // NaN is 0 for integers, not-a-number for floating point
+        assertValueEquals(NaN, Float.NaN);
+        assertValueEquals(NaN, Double.NaN);
+        assertValueEquals(NaN, 0L);
+        assertValueEquals(NaN, 0);
+        assertValueEquals(NaN, (short)0);
+
+        // Positive infinity, saturates upwards for integers
+        assertValueEquals(POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
+        assertValueEquals(POSITIVE_INFINITY, Double.POSITIVE_INFINITY);
+        assertValueEquals(POSITIVE_INFINITY, Long.MAX_VALUE);
+        assertValueEquals(POSITIVE_INFINITY, Integer.MAX_VALUE);
+        assertValueEquals(POSITIVE_INFINITY, (short)-1);
+
+        // Negative infinity, saturates downwards for integers
+        assertValueEquals(NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
+        assertValueEquals(NEGATIVE_INFINITY, Double.NEGATIVE_INFINITY);
+        assertValueEquals(NEGATIVE_INFINITY, Long.MIN_VALUE);
+        assertValueEquals(NEGATIVE_INFINITY, Integer.MIN_VALUE);
+        assertValueEquals(NEGATIVE_INFINITY, (short)0);
+
+        // Normal finite values, round down for integers
+        final Rational oneQuarter = new Rational(1, 4);
+        assertValueEquals(oneQuarter, 1.0f / 4.0f);
+        assertValueEquals(oneQuarter, 1.0 / 4.0);
+        assertValueEquals(oneQuarter, 0L);
+        assertValueEquals(oneQuarter, 0);
+        assertValueEquals(oneQuarter, (short)0);
+
+        final Rational nineFifths = new Rational(9, 5);
+        assertValueEquals(nineFifths, 9.0f / 5.0f);
+        assertValueEquals(nineFifths, 9.0 / 5.0);
+        assertValueEquals(nineFifths, 1L);
+        assertValueEquals(nineFifths, 1);
+        assertValueEquals(nineFifths, (short)1);
+
+        final Rational negativeHundred = new Rational(-1000, 10);
+        assertValueEquals(negativeHundred, -100.f / 1.f);
+        assertValueEquals(negativeHundred, -100.0 / 1.0);
+        assertValueEquals(negativeHundred, -100L);
+        assertValueEquals(negativeHundred, -100);
+        assertValueEquals(negativeHundred, (short)-100);
+
+        // Short truncates if the result is too large
+        assertValueEquals(new Rational(Integer.MAX_VALUE, 1), (short)Integer.MAX_VALUE);
+        assertValueEquals(new Rational(0x00FFFFFF, 1), (short)0x00FFFFFF);
+        assertValueEquals(new Rational(0x00FF00FF, 1), (short)0x00FF00FF);
+    }
+
+    @SmallTest
+    public void testSerialize() throws ClassNotFoundException, IOException {
+        /*
+         * Check correct [de]serialization
+         */
+        assertEqualsAfterSerializing(ZERO);
+        assertEqualsAfterSerializing(NaN);
+        assertEqualsAfterSerializing(NEGATIVE_INFINITY);
+        assertEqualsAfterSerializing(POSITIVE_INFINITY);
+        assertEqualsAfterSerializing(UNIT);
+        assertEqualsAfterSerializing(new Rational(100, 200));
+        assertEqualsAfterSerializing(new Rational(-100, 200));
+        assertEqualsAfterSerializing(new Rational(5, 1));
+        assertEqualsAfterSerializing(new Rational(Integer.MAX_VALUE, Integer.MIN_VALUE));
+
+        /*
+         * Check bad deserialization fails
+         */
+        try {
+            Rational badZero = createIllegalRational(0, 100); // [0, 100] , should be [0, 1]
+            Rational results = serializeRoundTrip(badZero);
+            fail("Deserializing " + results + " should not have succeeded");
+        } catch (InvalidObjectException e) {
+            // OK
+        }
+
+        try {
+            Rational badPosInfinity = createIllegalRational(100, 0); // [100, 0] , should be [1, 0]
+            Rational results = serializeRoundTrip(badPosInfinity);
+            fail("Deserializing " + results + " should not have succeeded");
+        } catch (InvalidObjectException e) {
+            // OK
+        }
+
+        try {
+            Rational badNegInfinity =
+                    createIllegalRational(-100, 0); // [-100, 0] , should be [-1, 0]
+            Rational results = serializeRoundTrip(badNegInfinity);
+            fail("Deserializing " + results + " should not have succeeded");
+        } catch (InvalidObjectException e) {
+            // OK
+        }
+
+        try {
+            Rational badReduced = createIllegalRational(2, 4); // [2,4] , should be [1, 2]
+            Rational results = serializeRoundTrip(badReduced);
+            fail("Deserializing " + results + " should not have succeeded");
+        } catch (InvalidObjectException e) {
+            // OK
+        }
+
+        try {
+            Rational badReducedNeg = createIllegalRational(-2, 4); // [-2, 4] should be [-1, 2]
+            Rational results = serializeRoundTrip(badReducedNeg);
+            fail("Deserializing " + results + " should not have succeeded");
+        } catch (InvalidObjectException e) {
+            // OK
+        }
+    }
+
+    private static void assertValueEquals(Rational object, float expected) {
+        assertEquals("Checking floatValue() for " + object + ";",
+                expected, object.floatValue());
+    }
+
+    private static void assertValueEquals(Rational object, double expected) {
+        assertEquals("Checking doubleValue() for " + object + ";",
+                expected, object.doubleValue());
+    }
+
+    private static void assertValueEquals(Rational object, long expected) {
+        assertEquals("Checking longValue() for " + object + ";",
+                expected, object.longValue());
+    }
+
+    private static void assertValueEquals(Rational object, int expected) {
+        assertEquals("Checking intValue() for " + object + ";",
+                expected, object.intValue());
+    }
+
+    private static void assertValueEquals(Rational object, short expected) {
+        assertEquals("Checking shortValue() for " + object + ";",
+                expected, object.shortValue());
+    }
+
+    private static void assertFinite(Rational object, boolean expected) {
+        assertAction("finite", object, expected, object.isFinite());
+    }
+
+    private static void assertInfinite(Rational object, boolean expected) {
+        assertAction("infinite", object, expected, object.isInfinite());
+    }
+
+    private static void assertNaN(Rational object, boolean expected) {
+        assertAction("NaN", object, expected, object.isNaN());
+    }
+
+    private static void assertZero(Rational object, boolean expected) {
+        assertAction("zero", object, expected, object.isZero());
+    }
+
+    private static <T> void assertAction(String action, T object, boolean expected,
+            boolean actual) {
+        String expectedMessage = expected ? action : ("not " + action);
+        assertEquals("Expected " + object + " to be " + expectedMessage,
+                expected, actual);
+    }
+
+    private static <T extends Comparable<? super T>> void assertLessThan(T left, T right) {
+        assertTrue("Expected (LR) left " + left + " to be less than right " + right,
+                left.compareTo(right) < 0);
+        assertTrue("Expected (RL) left " + left + " to be less than right " + right,
+                right.compareTo(left) > 0);
+    }
+
+    private static <T extends Comparable<? super T>> void assertGreaterThan(T left, T right) {
+        assertTrue("Expected (LR) left " + left + " to be greater than right " + right,
+                left.compareTo(right) > 0);
+        assertTrue("Expected (RL) left " + left + " to be greater than right " + right,
+                right.compareTo(left) < 0);
+    }
+
+    private static <T extends Comparable<? super T>> void assertCompareEquals(T left, T right) {
+        assertTrue("Expected (LR) left " + left + " to be compareEquals to right " + right,
+                left.compareTo(right) == 0);
+        assertTrue("Expected (RL) left " + left + " to be compareEquals to right " + right,
+                right.compareTo(left) == 0);
+    }
+
+    private static <T extends Serializable> byte[] serialize(T obj) throws IOException {
+        ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
+        try (ObjectOutputStream objectStream = new ObjectOutputStream(byteStream)) {
+            objectStream.writeObject(obj);
+        }
+        return byteStream.toByteArray();
+    }
+
+    private static <T extends Serializable> T deserialize(byte[] array, Class<T> klass)
+            throws IOException, ClassNotFoundException {
+        ByteArrayInputStream bais = new ByteArrayInputStream(array);
+        ObjectInputStream ois = new ObjectInputStream(bais);
+        Object obj = ois.readObject();
+        return klass.cast(obj);
+    }
+
+    @SuppressWarnings("unchecked")
+    private static <T extends Serializable> T serializeRoundTrip(T obj)
+            throws IOException, ClassNotFoundException {
+        Class<T> klass = (Class<T>) obj.getClass();
+        byte[] arr = serialize(obj);
+        T serialized = deserialize(arr, klass);
+        return serialized;
+    }
+
+    private static <T extends Serializable> void assertEqualsAfterSerializing(T obj)
+            throws ClassNotFoundException, IOException {
+        T serialized = serializeRoundTrip(obj);
+        assertEquals("Expected values to be equal after serialization round-trip", obj, serialized);
+    }
+
+    private static Rational createIllegalRational(int numerator, int denominator) {
+        Rational r = new Rational(numerator, denominator);
+        mutateField(r, "mNumerator", numerator);
+        mutateField(r, "mDenominator", denominator);
+        return r;
+    }
+
+    private static <T> void mutateField(T object, String name, int value) {
+        try {
+            Field f = object.getClass().getDeclaredField(name);
+            f.setAccessible(true);
+            f.set(object, value);
+        } catch (NoSuchFieldException e) {
+            throw new AssertionError(e);
+        } catch (IllegalAccessException e) {
+            throw new AssertionError(e);
+        } catch (IllegalArgumentException e) {
+            throw new AssertionError(e);
+        }
+    }
 }
