am d8858893: Merge "docs: fix some broken links" into eclair

Merge commit 'd88588935e3a09b4b13753d55dbe8a8e9ed240a1' into eclair-plus-aosp

* commit 'd88588935e3a09b4b13753d55dbe8a8e9ed240a1':
  docs: fix some broken links
diff --git a/core/java/android/app/ListActivity.java b/core/java/android/app/ListActivity.java
index 5523c18..19b99c8 100644
--- a/core/java/android/app/ListActivity.java
+++ b/core/java/android/app/ListActivity.java
@@ -152,7 +152,7 @@
  *         // Query for all people contacts using the {@link android.provider.Contacts.People} convenience class.
  *         // Put a managed wrapper around the retrieved cursor so we don't have to worry about
  *         // requerying or closing it as the activity changes state.
- *         mCursor = People.query(this.getContentResolver(), null);
+ *         mCursor = this.getContentResolver().query(People.CONTENT_URI, null, null, null, null);
  *         startManagingCursor(mCursor);
  * 
  *         // Now create a new list adapter bound to the cursor. 
@@ -161,9 +161,9 @@
  *                 this, // Context.
  *                 android.R.layout.two_line_list_item,  // Specify the row template to use (here, two columns bound to the two retrieved cursor 
  * rows).
- *                 mCursor,                                    // Pass in the cursor to bind to.
- *                 new String[] {People.NAME, People.COMPANY}, // Array of cursor columns to bind to.
- *                 new int[]);                                 // Parallel array of which template objects to bind to those columns.
+ *                 mCursor,                                              // Pass in the cursor to bind to.
+ *                 new String[] {People.NAME, People.COMPANY},           // Array of cursor columns to bind to.
+ *                 new int[] {android.R.id.text1, android.R.id.text2});  // Parallel array of which template objects to bind to those columns.
  * 
  *         // Bind to our new adapter.
  *         setListAdapter(adapter);
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
index 3716274..dd89097 100644
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ b/core/java/android/content/AbstractSyncableContentProvider.java
@@ -690,6 +690,7 @@
             while (c.moveToNext()) {
                 String accountName = c.getString(0);
                 String accountType = c.getString(1);
+		if ("localhost".equals(accountType)) continue;
                 if (TextUtils.isEmpty(accountName)) {
                     continue;
                 }
diff --git a/core/java/android/net/Uri.java b/core/java/android/net/Uri.java
index 298be3b..9a1b65d 100644
--- a/core/java/android/net/Uri.java
+++ b/core/java/android/net/Uri.java
@@ -1028,7 +1028,7 @@
         }
 
         private String parseHost() {
-            String authority = getAuthority();
+            String authority = getEncodedAuthority();
             if (authority == null) {
                 return null;
             }
@@ -1037,9 +1037,11 @@
             int userInfoSeparator = authority.indexOf('@');
             int portSeparator = authority.indexOf(':', userInfoSeparator);
 
-            return portSeparator == NOT_FOUND
+            String encodedHost = portSeparator == NOT_FOUND
                     ? authority.substring(userInfoSeparator + 1)
                     : authority.substring(userInfoSeparator + 1, portSeparator);
+
+            return decode(encodedHost);
         }
 
         private volatile int port = NOT_CALCULATED;
@@ -1051,7 +1053,7 @@
         }
 
         private int parsePort() {
-            String authority = getAuthority();
+            String authority = getEncodedAuthority();
             if (authority == null) {
                 return -1;
             }
@@ -1065,7 +1067,7 @@
                 return -1;
             }
 
-            String portString = authority.substring(portSeparator + 1);
+            String portString = decode(authority.substring(portSeparator + 1));
             try {
                 return Integer.parseInt(portString);
             } catch (NumberFormatException e) {
diff --git a/core/java/android/text/InputType.java b/core/java/android/text/InputType.java
index 14b8308..8592221 100644
--- a/core/java/android/text/InputType.java
+++ b/core/java/android/text/InputType.java
@@ -20,7 +20,25 @@
 
 /**
  * Bit definitions for an integer defining the basic content type of text
- * held in an {@link Editable} object.
+ * held in an {@link Editable} object. Supported classes may be combined
+ * with variations and flags to indicate desired behaviors.
+ *
+ * <h3>Examples</h3>
+ *
+ * <dl>
+ * <dt>A password field with with the password visible to the user:
+ * <dd>inputType = TYPE_CLASS_TEXT |
+ *     TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
+ *
+ * <dt>A multi-line postal address with automatic capitalization:
+ * <dd>inputType = TYPE_CLASS_TEXT |
+ *     TYPE_TEXT_VARIATION_POSTAL_ADDRESS |
+ *     TYPE_TEXT_FLAG_MULTI_LINE
+ *
+ * <dt>A time field:
+ * <dd>inputType = TYPE_CLASS_DATETIME |
+ *     TYPE_DATETIME_VARIATION_TIME
+ * </dl>
  */
 public interface InputType {
     /**
diff --git a/core/java/android/widget/ImageButton.java b/core/java/android/widget/ImageButton.java
index d417e40..2fc29bc 100644
--- a/core/java/android/widget/ImageButton.java
+++ b/core/java/android/widget/ImageButton.java
@@ -44,11 +44,11 @@
  * <pre>
  * &lt;?xml version="1.0" encoding="utf-8"?&gt;
  * &lt;selector xmlns:android="http://schemas.android.com/apk/res/android"&gt;
- *     &lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
  *     &lt;item android:state_pressed="true"
  *           android:drawable="@drawable/button_pressed" /&gt; &lt;!-- pressed --&gt;
  *     &lt;item android:state_focused="true"
  *           android:drawable="@drawable/button_focused" /&gt; &lt;!-- focused --&gt;
+ *     &lt;item android:drawable="@drawable/button_normal" /&gt; &lt;!-- default --&gt;
  * &lt;/selector&gt;</pre>
  *
  * <p>Save the XML file in your project {@code res/drawable/} folder and then 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index cdaba8a..455b593 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -5202,7 +5202,7 @@
             mDesiredHeightAtMeasure = desired;
 
             if (heightMode == MeasureSpec.AT_MOST) {
-                height = Math.min(desired, height);
+                height = Math.min(desired, heightSize);
             }
         }
 
diff --git a/core/jni/android_text_format_Time.cpp b/core/jni/android_text_format_Time.cpp
index fde6ca6..d89a7e6 100644
--- a/core/jni/android_text_format_Time.cpp
+++ b/core/jni/android_text_format_Time.cpp
@@ -382,7 +382,7 @@
     jchar c = s[spos];
     if (c != expected) {
         char msg[100];
-	sprintf(msg, "Unexpected %c at pos=%d.  Expected %c.", c, spos,
+	sprintf(msg, "Unexpected character 0x%02x at pos=%d.  Expected %c.", c, spos,
 		expected);
 	jniThrowException(env, "android/util/TimeFormatException", msg);
 	return false;
@@ -483,6 +483,12 @@
     int n;
     jboolean inUtc = false;
 
+    if (len < 10) {
+        jniThrowException(env, "android/util/TimeFormatException",
+                "Time input is too short; must be at least 10 characters");
+        return false;
+    }
+
     // year
     n = get_char(env, s, 0, 1000, &thrown);    
     n += get_char(env, s, 1, 100, &thrown);
@@ -510,7 +516,7 @@
     if (thrown) return false;
     env->SetIntField(This, g_mdayField, n);
 
-    if (len >= 17) {
+    if (len >= 19) {
         // T
         if (!check_char(env, s, 10, 'T')) return false;
 
@@ -541,10 +547,19 @@
         if (thrown) return false;
         env->SetIntField(This, g_secField, n);
 
-	// skip the '.XYZ' -- we don't care about subsecond precision.
+        // skip the '.XYZ' -- we don't care about subsecond precision.
+        int tz_index = 19;
+        if (tz_index < len && s[tz_index] == '.') {
+            do {
+                tz_index++;
+            } while (tz_index < len
+                && s[tz_index] >= '0'
+                && s[tz_index] <= '9');
+        }
+
         int offset = 0;
-	if (len >= 23) {
-	    char c = s[23];
+        if (len > tz_index) {
+            char c = s[tz_index];
 
 	    // NOTE: the offset is meant to be subtracted to get from local time
 	    // to UTC.  we therefore use 1 for '-' and -1 for '+'.
@@ -561,27 +576,34 @@
 	        break;
 	    default:
 	        char msg[100];
-	        sprintf(msg, "Unexpected %c at position 19.  Expected + or -",
-			c);
+	        sprintf(msg, "Unexpected character 0x%02x at position %d.  Expected + or -",
+			c, tz_index);
 	        jniThrowException(env, "android/util/TimeFormatException", msg);
 	        return false;
 	    }
             inUtc = true;
 
 	    if (offset != 0) {
+	        if (len < tz_index + 5) {
+	            char msg[100];
+	            sprintf(msg, "Unexpected length; should be %d characters", tz_index + 5);
+	            jniThrowException(env, "android/util/TimeFormatException", msg);
+	            return false;
+	        }
+
 	        // hour
-	        n = get_char(env, s, 24, 10, &thrown);
-		n += get_char(env, s, 25, 1, &thrown);
+	        n = get_char(env, s, tz_index + 1, 10, &thrown);
+		n += get_char(env, s, tz_index + 2, 1, &thrown);
 		if (thrown) return false;
 		n *= offset;
 		hour += n;
 
 		// :
-		if (!check_char(env, s, 26, ':')) return false;
+		if (!check_char(env, s, tz_index + 3, ':')) return false;
 	    
 		// minute
-		n = get_char(env, s, 27, 10, &thrown);
-		n += get_char(env, s, 28, 1, &thrown);
+		n = get_char(env, s, tz_index + 4, 10, &thrown);
+		n += get_char(env, s, tz_index + 5, 1, &thrown);
 		if (thrown) return false;
 		n *= offset;
 		minute += n;
diff --git a/docs/html/guide/publishing/versioning.jd b/docs/html/guide/publishing/versioning.jd
index 216f993..16fc356 100644
--- a/docs/html/guide/publishing/versioning.jd
+++ b/docs/html/guide/publishing/versioning.jd
@@ -117,7 +117,7 @@
 <p>In this example, note that <code>android:versionCode</code> value indicates
 that the current .apk contains the second release of the application code, which
 corresponds to a minor follow-on release, as shown by the
-<code>android:codeName</code> string. </p>
+<code>android:versionName</code> string. </p>
 
 <p>The Android framework provides an API to let applications query the system
 for version information about your application. To obtain version information,
diff --git a/docs/html/guide/topics/fundamentals.jd b/docs/html/guide/topics/fundamentals.jd
index 71705d3..640e44b 100644
--- a/docs/html/guide/topics/fundamentals.jd
+++ b/docs/html/guide/topics/fundamentals.jd
@@ -72,8 +72,8 @@
 runs in isolation from the code of all other applications.</li>
 
 <li>By default, each application is assigned a unique Linux user ID.  
-Permissions are set so that the application's files are visible only 
-that user, only to the application itself &mdash; although there are ways 
+Permissions are set so that the application's files are visible only to
+that user and only to the application itself &mdash; although there are ways
 to export them to other applications as well.</li>
 </ul>
 
diff --git a/docs/html/guide/tutorials/views/hello-mapview.jd b/docs/html/guide/tutorials/views/hello-mapview.jd
index 531300f..7a21485 100644
--- a/docs/html/guide/tutorials/views/hello-mapview.jd
+++ b/docs/html/guide/tutorials/views/hello-mapview.jd
@@ -93,28 +93,6 @@
 }
 </pre>
 <p>You can actually run this now, but all it does is allow you to pan around the map.</p>
-<p>Android provides a handy {@link android.widget.ZoomControls} widget for zooming in and out of a View. 
-MapView can automatically hook one for us by requesting it with the <code>getZoomControls()</code>
-method. Let's do this.</p>
-
-<li>Go back to the layout file. We need a new ViewGroup element, in which we'll 
-   place the ZoomControls. Just below the MapView element (but inside the RelativeLayout), add this element:
-<pre>
-&lt;LinearLayout
-    android:id="@+id/zoomview"
-    android:layout_width="wrap_content"
-    android:layout_height="wrap_content"
-    android:layout_alignBottom="@id/mapview"
-    android:layout_centerHorizontal="true"
-/></pre>
-
-      <p>It doesn't really matter what kind of ViewGroup we use, because we just want a 
-      container that we can position within our root RelativeLayout.</p>
-
-      <p>The last two attributes are available only to an element that's a child of a 
-      RelativeLayout. <code>layout_alignBottom</code> aligns the bottom of this element to the bottom of 
-      the element identified with a resource tag (which must be a sibling to this element). 
-      <code>layout_centerHorizontal</code> centers this on the horizontal plane.</p></li>
 
    <li>Now go back to the HelloMapView class. We'll now retrieve the ZoomControls object from 
    the MapView and add it to our new layout element. First, at the top of the HelloMapView, 
@@ -122,24 +100,18 @@
 <pre>
 LinearLayout linearLayout;
 MapView mapView;
-ZoomControls mZoom;</pre></li>
+</pre>
 
    <li>Then initialize each of these in <code>onCreate()</code>. We'll capture the LinearLayout and 
    MapView through their layout resources. Then get the ZoomControls from the MapView::
 <pre>
-linearLayout = (LinearLayout) findViewById(R.id.zoomview);
 mapView = (MapView) findViewById(R.id.mapview);
-mZoom = (ZoomControls) mapView.getZoomControls();</pre>
+mapView.setBuiltInZoomControls(true);
+</pre>
 
-      <p>By using the ZoomControls object provided by MapView, we don't have to do any of the work
-      required to actually perform the zoom operations. The ZoomControls widget that MapView 
-      returns for us is already hooked into the MapView and works as soon as we add it to the 
-      layout. The controls will appear whenever the user touches the map, then dissapear after 
-      a few moments of inactivity.</p></li>
-
-   <li>Now just plug our ZoomControls into the LinearLayout we added:
-
-      <pre>linearLayout.addView(mZoom);</pre></li>
+      <p>By using the built-in zoom control provided by MapView, we don't have to do any of the work
+      required to actually perform the zoom operations. The controls will appear whenever the user
+      touches the map, then disappear after a few moments of inactivity.</p></li>
 
    <li>Run it.</li>
 </ol>
diff --git a/graphics/java/android/graphics/ColorMatrix.java b/graphics/java/android/graphics/ColorMatrix.java
index 2478712e..c22cda1 100644
--- a/graphics/java/android/graphics/ColorMatrix.java
+++ b/graphics/java/android/graphics/ColorMatrix.java
@@ -110,22 +110,31 @@
         a[18] = aScale;
     }
     
+    /**
+     * Set the rotation on a color axis by the specified values.
+     * axis=0 correspond to a rotation around the RED color
+     * axis=1 correspond to a rotation around the GREEN color
+     * axis=2 correspond to a rotation around the BLUE color
+     */
     public void setRotate(int axis, float degrees) {
         reset();
         float radians = degrees * (float)Math.PI / 180;
         float cosine = FloatMath.cos(radians);
         float sine = FloatMath.sin(radians);
         switch (axis) {
+        // Rotation around the red color
         case 0:
             mArray[6] = mArray[12] = cosine;
             mArray[7] = sine;
             mArray[11] = -sine;
             break;
+        // Rotation around the green color
         case 1:
-            mArray[0] = mArray[17] = cosine;
-            mArray[2] = sine;
-            mArray[15] = -sine;
+            mArray[0] = mArray[12] = cosine;
+            mArray[2] = -sine;
+            mArray[10] = sine;
             break;
+        // Rotation around the blue color
         case 2:
             mArray[0] = mArray[6] = cosine;
             mArray[1] = sine;
diff --git a/include/media/mediaplayer.h b/include/media/mediaplayer.h
index b91b47e..7132b18 100644
--- a/include/media/mediaplayer.h
+++ b/include/media/mediaplayer.h
@@ -75,7 +75,7 @@
 // 'notify' is invoked with the following:
 //   'msg' is set to MEDIA_INFO.
 //   'ext1' should be a value from the enum media_info_type.
-//   'ext2' contains an implementation dependant error code to provide
+//   'ext2' contains an implementation dependant info code to provide
 //          more details. Should default to 0 when not used.
 //
 // The codes are distributed as follow:
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index a676782..07542ed7 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -722,7 +722,8 @@
     }
 
     /**
-     * Sets the data source (FileDescriptor) to use.  It is the caller's responsibility
+     * Sets the data source (FileDescriptor) to use.  The FileDescriptor must be
+     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
      * to close the file descriptor. It is safe to do so as soon as this call returns.
      *
      * @param fd the FileDescriptor for the file you want to play
@@ -871,8 +872,10 @@
      * Returns the width of the video.
      *
      * @return the width of the video, or 0 if there is no video,
-     * no display surface was set, or prepare()/prepareAsync()
-     * have not completed yet
+     * no display surface was set, or the width has not been determined
+     * yet. The OnVideoSizeChangedListener can be registered via
+     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     * to provide a notification when the width is available.
      */
     public native int getVideoWidth();
 
@@ -880,8 +883,10 @@
      * Returns the height of the video.
      *
      * @return the height of the video, or 0 if there is no video,
-     * no display surface was set, or prepare()/prepareAsync()
-     * have not completed yet
+     * no display surface was set, or the height has not been determined
+     * yet. The OnVideoSizeChangedListener can be registered via
+     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     * to provide a notification when the height is available.
      */
     public native int getVideoHeight();
 
diff --git a/media/java/android/media/Ringtone.java b/media/java/android/media/Ringtone.java
index f988d2b..0ce3526 100644
--- a/media/java/android/media/Ringtone.java
+++ b/media/java/android/media/Ringtone.java
@@ -139,11 +139,17 @@
                     cursor = res.query(uri, MEDIA_COLUMNS, null, null, null);
                 }
                 
-                if (cursor != null && cursor.getCount() == 1) {
-                    cursor.moveToFirst();
-                    return cursor.getString(2);
-                } else {
-                    title = uri.getLastPathSegment();
+                try {
+                    if (cursor != null && cursor.getCount() == 1) {
+                        cursor.moveToFirst();
+                        return cursor.getString(2);
+                    } else {
+                        title = uri.getLastPathSegment();
+                    }
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
                 }
             }
         }
diff --git a/opengl/java/android/opengl/GLLogWrapper.java b/opengl/java/android/opengl/GLLogWrapper.java
index 4119bf8..f332448 100644
--- a/opengl/java/android/opengl/GLLogWrapper.java
+++ b/opengl/java/android/opengl/GLLogWrapper.java
@@ -1517,7 +1517,7 @@
         arg("count", count);
         startLogIndices();
         for (int i = 0; i < count; i++) {
-            doElement(mStringBuilder, i, first + count);
+            doElement(mStringBuilder, i, first + i);
         }
         endLogIndices();
         end();
diff --git a/opengl/libagl/egl.cpp b/opengl/libagl/egl.cpp
index 781b8c3..81864bd 100644
--- a/opengl/libagl/egl.cpp
+++ b/opengl/libagl/egl.cpp
@@ -1205,7 +1205,7 @@
                 gConfigManagement,
                 0, NELEM(gConfigManagement)-1,
                 attr);
-        if (index >= 0) {
+        if (cfgMgtIndex >= 0) {
             bool match = gConfigManagement[cfgMgtIndex].match(
                     val, configFound[index].value);
             if (match) {
diff --git a/preloaded-classes b/preloaded-classes
index c4b1c66..75abada 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -1642,10 +1642,7 @@
 org.apache.harmony.lang.annotation.AnnotationMember$DefaultValues
 org.apache.harmony.luni.internal.net.www.protocol.http.HttpConfiguration
 org.apache.harmony.luni.internal.net.www.protocol.http.HttpConnection
-org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection
-org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnection$LimitedInputStream
 org.apache.harmony.luni.internal.net.www.protocol.jar.Handler
-org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnection
 org.apache.harmony.luni.internal.util.TimezoneGetter
 org.apache.harmony.luni.internal.util.ZoneInfo
 org.apache.harmony.luni.internal.util.ZoneInfoDB
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index bbb43d7..4c3893c 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -1315,7 +1315,7 @@
 
     /**
      * @return null if the provider does not exits
-     * @throw SecurityException if the provider is not allowed to be
+     * @throws SecurityException if the provider is not allowed to be
      * accessed by the caller
      */
     public Bundle getProviderInfo(String provider) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index f3cba69..84db13d 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -4140,7 +4140,7 @@
      * @param resultCode Result code, if any, from this Activity.
      * @param resultData Result data (Intent), if any, from this Activity.
      * 
-     * @result Returns true if the activity successfully finished, or false if it is still running.
+     * @return Returns true if the activity successfully finished, or false if it is still running.
      */
     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
         // Refuse possible leaked file descriptors
@@ -6073,6 +6073,7 @@
         }
         // If the target requires a specific UID, always fail for others.
         if (reqUid >= 0 && uid != reqUid) {
+            Log.w(TAG, "Permission denied: checkComponentPermission() reqUid=" + reqUid);
             return PackageManager.PERMISSION_DENIED;
         }
         if (permission == null) {
diff --git a/test-runner/android/test/ApplicationTestCase.java b/test-runner/android/test/ApplicationTestCase.java
index 31b226a..ae5fa4d 100644
--- a/test-runner/android/test/ApplicationTestCase.java
+++ b/test-runner/android/test/ApplicationTestCase.java
@@ -53,7 +53,7 @@
  * Context.
  * You can create and inject alternative types of Contexts by calling 
  * {@link AndroidTestCase#setContext(Context) setContext()}.  You must do this <i>before</i> calling
- * startApplication().  The test framework provides a
+ * {@link #createApplication()}.  The test framework provides a
  * number of alternatives for Context, including {@link android.test.mock.MockContext MockContext}, 
  * {@link android.test.RenamingDelegatingContext RenamingDelegatingContext}, and 
  * {@link android.content.ContextWrapper ContextWrapper}.
diff --git a/tests/AndroidTests/src/com/android/unit_tests/TimeTest.java b/tests/AndroidTests/src/com/android/unit_tests/TimeTest.java
index 110caa4..3b33a99 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/TimeTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/TimeTest.java
@@ -20,6 +20,7 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.text.format.Time;
 import android.util.Log;
+import android.util.TimeFormatException;
 
 import junit.framework.TestCase;
 
@@ -354,6 +355,86 @@
     }
 
     @SmallTest
+    public void testParse33390() throws Exception {
+        Time t = new Time(Time.TIMEZONE_UTC);
+
+        t.parse3339("1980-05-23");
+        if (!t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23) {
+            fail("Did not parse all-day date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != 0) {
+            fail("Did not parse timezone-offset-less date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50Z");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != 0) {
+            fail("Did not parse UTC date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50.0Z");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != 0) {
+            fail("Did not parse UTC date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50.12Z");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != 0) {
+            fail("Did not parse UTC date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50.123Z");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != 0) {
+            fail("Did not parse UTC date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50-06:00");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != -6*3600) {
+            fail("Did not parse timezone-offset date correctly");
+        }
+
+        t.parse3339("1980-05-23T09:50:50.123-06:00");
+        if (t.allDay || t.year != 1980 || t.month != 05 || t.monthDay != 23 ||
+                t.hour != 9 || t.minute != 50 || t.second != 50 ||
+                t.gmtoff != -6*3600) {
+            fail("Did not parse timezone-offset date correctly");
+        }
+
+        try {
+            t.parse3339("1980");
+            fail("Did not throw error on truncated input length");
+        } catch (TimeFormatException e) {
+            // Successful
+        }
+
+        try {
+            t.parse3339("1980-05-23T09:50:50.123+");
+            fail("Did not throw error on truncated timezone offset");
+        } catch (TimeFormatException e1) {
+            // Successful
+        }
+
+        try {
+            t.parse3339("1980-05-23T09:50:50.123+05:0");
+            fail("Did not throw error on truncated timezone offset");
+        } catch (TimeFormatException e1) {
+            // Successful
+        }
+    }
+
+    @SmallTest
     public void testSet0() throws Exception {
         Time t = new Time(Time.TIMEZONE_UTC);
         t.set(1000L);
diff --git a/tests/AndroidTests/src/com/android/unit_tests/UriTest.java b/tests/AndroidTests/src/com/android/unit_tests/UriTest.java
index 0abbc9a..d17e2c3 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/UriTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/UriTest.java
@@ -171,6 +171,11 @@
         assertEquals("bob lee", uri.getUserInfo());
         assertEquals("bob%20lee", uri.getEncodedUserInfo());
 
+        uri = Uri.parse("http://bob%40lee%3ajr@local%68ost:4%32");
+        assertEquals("bob@lee:jr", uri.getUserInfo());
+        assertEquals("localhost", uri.getHost());
+        assertEquals(42, uri.getPort());
+
         uri = Uri.parse("http://localhost");
         assertEquals("localhost", uri.getHost());
         assertEquals(-1, uri.getPort());
diff --git a/tools/aapt/Command.cpp b/tools/aapt/Command.cpp
index 8be9db3..3a30c0af 100644
--- a/tools/aapt/Command.cpp
+++ b/tools/aapt/Command.cpp
@@ -401,7 +401,7 @@
             ResXMLTree tree;
             asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
             if (asset == NULL) {
-                fprintf(stderr, "ERROR: dump failed because resource %p found\n", resname);
+                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
                 goto bail;
             }
 
@@ -427,7 +427,7 @@
             ResXMLTree tree;
             asset = assets.openNonAsset(resname, Asset::ACCESS_BUFFER);
             if (asset == NULL) {
-                fprintf(stderr, "ERROR: dump failed because resource %p found\n", resname);
+                fprintf(stderr, "ERROR: dump failed because resource %s found\n", resname);
                 goto bail;
             }
 
diff --git a/tools/aapt/StringPool.cpp b/tools/aapt/StringPool.cpp
index 878d3b1..715170a 100644
--- a/tools/aapt/StringPool.cpp
+++ b/tools/aapt/StringPool.cpp
@@ -228,7 +228,7 @@
         }
         dat += (preSize+strPos)/sizeof(uint16_t);
         if (lenSize > sizeof(uint16_t)) {
-            *dat = htods(0x8000 | ((strSize>>16)&0x7ffff));
+            *dat = htods(0x8000 | ((strSize>>16)&0x7fff));
             dat++;
         }
         *dat++ = htods(strSize);