Merge change 2109 into donut

* changes:
  Add option for gtalk stream compression
diff --git a/api/current.xml b/api/current.xml
index 6fe382d..3c4d482 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -85846,6 +85846,16 @@
  visibility="public"
 >
 </field>
+<field name="MANUFACTURER"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="MODEL"
  type="java.lang.String"
  transient="false"
diff --git a/cmds/backup/Android.mk b/cmds/backup/Android.mk
index a37a80e..508aec0 100644
--- a/cmds/backup/Android.mk
+++ b/cmds/backup/Android.mk
@@ -5,7 +5,7 @@
 
 LOCAL_SRC_FILES:= backup.cpp
 
-LOCAL_SHARED_LIBRARIES := libcutils libc libutils
+LOCAL_SHARED_LIBRARIES := libcutils libutils
 
 LOCAL_MODULE:= btool
 
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 4a4285e..101336b 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -38,6 +38,9 @@
     /** The name of the underlying board, like "goldfish". */
     public static final String BOARD = getString("ro.product.board");
 
+    /** The manufacturer of the product/hardware. */
+    public static final String MANUFACTURER = getString("ro.product.manufacturer");
+
     /** The brand (e.g., carrier) the software is customized for, if any. */
     public static final String BRAND = getString("ro.product.brand");
 
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 4297be0..40a72a4 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -3701,6 +3701,54 @@
     }
 
     @Override
+    public void invalidateDrawable(Drawable drawable) {
+        if (verifyDrawable(drawable)) {
+            final Rect dirty = drawable.getBounds();
+            int scrollX = mScrollX;
+            int scrollY = mScrollY;
+
+            // IMPORTANT: The coordinates below are based on the coordinates computed
+            // for each compound drawable in onDraw(). Make sure to update each section
+            // accordingly.
+            final TextView.Drawables drawables = mDrawables;
+            if (drawables != null) {
+                if (drawable == drawables.mDrawableLeft) {
+                    final int compoundPaddingTop = getCompoundPaddingTop();
+                    final int compoundPaddingBottom = getCompoundPaddingBottom();
+                    final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;
+
+                    scrollX += mPaddingLeft;
+                    scrollY += compoundPaddingTop + (vspace - drawables.mDrawableHeightLeft) / 2;
+                } else if (drawable == drawables.mDrawableRight) {
+                    final int compoundPaddingTop = getCompoundPaddingTop();
+                    final int compoundPaddingBottom = getCompoundPaddingBottom();
+                    final int vspace = mBottom - mTop - compoundPaddingBottom - compoundPaddingTop;
+
+                    scrollX += (mRight - mLeft - mPaddingRight - drawables.mDrawableSizeRight);
+                    scrollY += compoundPaddingTop + (vspace - drawables.mDrawableHeightRight) / 2;
+                } else if (drawable == drawables.mDrawableTop) {
+                    final int compoundPaddingLeft = getCompoundPaddingLeft();
+                    final int compoundPaddingRight = getCompoundPaddingRight();
+                    final int hspace = mRight - mLeft - compoundPaddingRight - compoundPaddingLeft;
+
+                    scrollX += compoundPaddingLeft + (hspace - drawables.mDrawableWidthTop) / 2;
+                    scrollY += mPaddingTop;
+                } else if (drawable == drawables.mDrawableBottom) {
+                    final int compoundPaddingLeft = getCompoundPaddingLeft();
+                    final int compoundPaddingRight = getCompoundPaddingRight();
+                    final int hspace = mRight - mLeft - compoundPaddingRight - compoundPaddingLeft;
+
+                    scrollX += compoundPaddingLeft + (hspace - drawables.mDrawableWidthBottom) / 2;
+                    scrollY += (mBottom - mTop - mPaddingBottom - drawables.mDrawableSizeBottom);
+                }
+            }
+
+            invalidate(dirty.left + scrollX, dirty.top + scrollY,
+                    dirty.right + scrollX, dirty.bottom + scrollY);
+        }
+    }
+
+    @Override
     protected void onDraw(Canvas canvas) {
         restartMarqueeIfNeeded();
 
@@ -3728,6 +3776,8 @@
             int vspace = bottom - top - compoundPaddingBottom - compoundPaddingTop;
             int hspace = right - left - compoundPaddingRight - compoundPaddingLeft;
 
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
             if (dr.mDrawableLeft != null) {
                 canvas.save();
                 canvas.translate(scrollX + mPaddingLeft,
@@ -3737,6 +3787,8 @@
                 canvas.restore();
             }
 
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
             if (dr.mDrawableRight != null) {
                 canvas.save();
                 canvas.translate(scrollX + right - left - mPaddingRight - dr.mDrawableSizeRight,
@@ -3745,6 +3797,8 @@
                 canvas.restore();
             }
 
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
             if (dr.mDrawableTop != null) {
                 canvas.save();
                 canvas.translate(scrollX + compoundPaddingLeft + (hspace - dr.mDrawableWidthTop) / 2,
@@ -3753,6 +3807,8 @@
                 canvas.restore();
             }
 
+            // IMPORTANT: The coordinates computed are also used in invalidateDrawable()
+            // Make sure to update invalidateDrawable() when changing this code.
             if (dr.mDrawableBottom != null) {
                 canvas.save();
                 canvas.translate(scrollX + compoundPaddingLeft +
diff --git a/include/utils/Parcel.h b/include/utils/Parcel.h
index 9087c44..af1490a 100644
--- a/include/utils/Parcel.h
+++ b/include/utils/Parcel.h
@@ -80,8 +80,11 @@
     status_t            writeStrongBinder(const sp<IBinder>& val);
     status_t            writeWeakBinder(const wp<IBinder>& val);
 
-    // doesn't take ownership of the native_handle
-    status_t            writeNativeHandle(const native_handle& handle);
+    // Place a native_handle into the parcel (the native_handle's file-
+    // descriptors are dup'ed, so it is safe to delete the native_handle
+    // when this function returns). 
+    // Doesn't take ownership of the native_handle.
+    status_t            writeNativeHandle(const native_handle* handle);
     
     // Place a file descriptor into the parcel.  The given fd must remain
     // valid for the lifetime of the parcel.
@@ -114,12 +117,11 @@
     wp<IBinder>         readWeakBinder() const;
 
     
-    // if alloc is NULL, native_handle is allocated with malloc(), otherwise
-    // alloc is used. If the function fails, the effects of alloc() must be
-    // reverted by the caller.
-    native_handle*     readNativeHandle(
-            native_handle* (*alloc)(void* cookie, int numFds, int ints),
-            void* cookie) const;
+    // Retrieve native_handle from the parcel. This returns a copy of the
+    // parcel's native_handle (the caller takes ownership). The caller
+    // must free the native_handle with native_handle_close() and 
+    // native_handle_delete().
+    native_handle*     readNativeHandle() const;
 
     
     // Retrieve a file descriptor from the parcel.  This returns the raw fd
diff --git a/libs/ui/Overlay.cpp b/libs/ui/Overlay.cpp
index b236edc..59c6514 100644
--- a/libs/ui/Overlay.cpp
+++ b/libs/ui/Overlay.cpp
@@ -129,12 +129,8 @@
 OverlayRef::~OverlayRef()
 {
     if (mOwnHandle) {
-        /* FIXME: handles should be promoted to "real" API and be handled by 
-         * the framework */
-        for (int i=0 ; i<mOverlayHandle->numFds ; i++) {
-            close(mOverlayHandle->data[i]);
-        }
-        free((void*)mOverlayHandle);
+        native_handle_close(mOverlayHandle);
+        native_handle_delete(const_cast<native_handle*>(mOverlayHandle));
     }
 }
 
@@ -147,7 +143,7 @@
         uint32_t f = data.readInt32();
         uint32_t ws = data.readInt32();
         uint32_t hs = data.readInt32();
-        native_handle* handle = data.readNativeHandle(NULL, NULL);
+        native_handle* handle = data.readNativeHandle();
 
         result = new OverlayRef();
         result->mOverlayHandle = handle;
@@ -169,7 +165,7 @@
         reply->writeInt32(o->mFormat);
         reply->writeInt32(o->mWidthStride);
         reply->writeInt32(o->mHeightStride);
-        reply->writeNativeHandle(*(o->mOverlayHandle));
+        reply->writeNativeHandle(o->mOverlayHandle);
     } else {
         reply->writeStrongBinder(NULL);
     }
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index 0f4b647..e74ad4a 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -650,28 +650,26 @@
     return flatten_binder(ProcessState::self(), val, this);
 }
 
-status_t Parcel::writeNativeHandle(const native_handle& handle)
+status_t Parcel::writeNativeHandle(const native_handle* handle)
 {
-    if (handle.version != sizeof(native_handle))
+    if (handle->version != sizeof(native_handle))
         return BAD_TYPE;
 
     status_t err;
-    err = writeInt32(handle.numFds);
+    err = writeInt32(handle->numFds);
     if (err != NO_ERROR) return err;
 
-    err = writeInt32(handle.numInts);
+    err = writeInt32(handle->numInts);
     if (err != NO_ERROR) return err;
 
-    for (int i=0 ; err==NO_ERROR && i<handle.numFds ; i++)
-        err = writeDupFileDescriptor(handle.data[i]);
+    for (int i=0 ; err==NO_ERROR && i<handle->numFds ; i++)
+        err = writeDupFileDescriptor(handle->data[i]);
 
     if (err != NO_ERROR) {
         LOGD("write native handle, write dup fd failed");
         return err;
     }
-
-    err = write(handle.data + handle.numFds, sizeof(int)*handle.numInts);
-
+    err = write(handle->data + handle->numFds, sizeof(int)*handle->numInts);
     return err;
 }
 
@@ -928,7 +926,7 @@
 }
 
 
-native_handle* Parcel::readNativeHandle(native_handle* (*alloc)(void*, int, int), void* cookie) const
+native_handle* Parcel::readNativeHandle() const
 {
     int numFds, numInts;
     status_t err;
@@ -937,31 +935,15 @@
     err = readInt32(&numInts);
     if (err != NO_ERROR) return 0;
 
-    native_handle* h;
-    if (alloc == 0) {
-        size_t size = sizeof(native_handle) + sizeof(int)*(numFds + numInts);
-        h = (native_handle*)malloc(size); 
-        h->version = sizeof(native_handle);
-        h->numFds = numFds;
-        h->numInts = numInts;
-    } else {
-        h = alloc(cookie, numFds, numInts);
-        if (h->version != sizeof(native_handle)) {
-            return 0;
-        }
-    }
-    
+    native_handle* h = native_handle_create(numFds, numInts);
     for (int i=0 ; err==NO_ERROR && i<numFds ; i++) {
         h->data[i] = dup(readFileDescriptor());
         if (h->data[i] < 0) err = BAD_VALUE;
     }
-    
     err = read(h->data + numFds, sizeof(int)*numInts);
-    
     if (err != NO_ERROR) {
-        if (alloc == 0) {
-            free(h);
-        }
+        native_handle_close(h);
+        native_handle_delete(h);
         h = 0;
     }
     return h;
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 565859c..9003848 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -641,6 +641,16 @@
         if ("delete_aiding_data".equals(command)) {
             return deleteAidingData(extras);
         }
+        if ("force_time_injection".equals(command)) {
+            return forceTimeInjection();
+        }
+        if ("force_xtra_injection".equals(command)) {
+            if (native_supports_xtra() && mNetworkThread != null) {
+                xtraDownloadRequest();
+                return true;
+            }
+            return false;
+        }
         
         Log.w(TAG, "sendExtraCommand: unknown command " + command);
         return false;
@@ -676,6 +686,15 @@
         return false;
     }
 
+    private boolean forceTimeInjection() {
+        if (Config.LOGD) Log.d(TAG, "forceTimeInjection");
+        if (mNetworkThread != null) {
+            mNetworkThread.timeInjectRequest();
+            return true;
+        }
+        return false;
+    }
+
     public void startNavigating() {
         if (!mStarted) {
             if (DEBUG) Log.d(TAG, "startNavigating");
@@ -1004,6 +1023,7 @@
 
         private long mNextNtpTime = 0;
         private long mNextXtraTime = 0;
+        private boolean mTimeInjectRequested = false;
         private boolean mXtraDownloadRequested = false;
         private boolean mDone = false;
 
@@ -1054,16 +1074,17 @@
                     }
                     waitTime = getWaitTime();
                 } while (!mDone && ((!mXtraDownloadRequested &&
-                        !mSetSuplServer && !mSetC2KServer && waitTime > 0)
+                        !mTimeInjectRequested && !mSetSuplServer && !mSetC2KServer && waitTime > 0)
                         || !mNetworkAvailable));
                 if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop");
                 
                 if (!mDone) {
                     if (mNtpServer != null && 
-                            mNextNtpTime <= System.currentTimeMillis()) {
+                            (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) {
                         if (Config.LOGD) {
                             Log.d(TAG, "Requesting time from NTP server " + mNtpServer);
                         }
+                        mTimeInjectRequested = false;
                         if (client.requestTime(mNtpServer, 10000)) {
                             long time = client.getNtpTime();
                             long timeReference = client.getNtpTimeReference();
@@ -1096,6 +1117,7 @@
                     if ((mXtraDownloadRequested || 
                             (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis()))
                             && xtraDownloader != null) {
+                        mXtraDownloadRequested = false;
                         byte[] data = xtraDownloader.downloadXtraData();
                         if (data != null) {
                             if (Config.LOGD) {
@@ -1103,7 +1125,6 @@
                             }
                             native_inject_xtra_data(data, data.length);
                             mNextXtraTime = 0;
-                            mXtraDownloadRequested = false;
                         } else {
                             mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL;
                         }
@@ -1118,6 +1139,11 @@
             notify();
         }
 
+        synchronized void timeInjectRequest() {
+            mTimeInjectRequested = true;
+            notify();
+        }
+
         synchronized void signal() {
             notify();
         }