Code drop from //branches/cupcake/...@124589
diff --git a/include/utils/IPCThreadState.h b/include/utils/IPCThreadState.h
index 47043b8..0490fd3 100644
--- a/include/utils/IPCThreadState.h
+++ b/include/utils/IPCThreadState.h
@@ -20,6 +20,7 @@
 #include <utils/Errors.h>
 #include <utils/Parcel.h>
 #include <utils/ProcessState.h>
+#include <utils/Vector.h>
 
 #ifdef HAVE_WIN32_PROC
 typedef  int  uid_t;
@@ -92,6 +93,8 @@
                                            void* cookie);
     
     const   sp<ProcessState>    mProcess;
+            Vector<BBinder*>    mPendingStrongDerefs;
+            Vector<RefBase::weakref_type*> mPendingWeakDerefs;
                                 
             Parcel              mIn;
             Parcel              mOut;
diff --git a/include/utils/MemoryHeapPmem.h b/include/utils/MemoryHeapPmem.h
index b694b20..60335ad 100644
--- a/include/utils/MemoryHeapPmem.h
+++ b/include/utils/MemoryHeapPmem.h
@@ -23,7 +23,7 @@
 #include <utils/MemoryDealer.h>
 #include <utils/MemoryHeapBase.h>
 #include <utils/IMemory.h>
-#include <utils/Vector.h>
+#include <utils/SortedVector.h>
 
 namespace android {
 
@@ -31,11 +31,21 @@
 
 // ---------------------------------------------------------------------------
 
-class SubRegionMemory;
-
 class MemoryHeapPmem : public HeapInterface, public MemoryHeapBase
 {
 public:
+    class MemoryPmem : public BnMemory {
+    public:
+        MemoryPmem(const sp<MemoryHeapPmem>& heap);
+        ~MemoryPmem();
+    protected:
+        const sp<MemoryHeapPmem>&  getHeap() const { return mClientHeap; }
+    private:
+        friend class MemoryHeapPmem;
+        virtual void revoke() = 0;
+        sp<MemoryHeapPmem>  mClientHeap;
+    };
+    
     MemoryHeapPmem(const sp<MemoryHeapBase>& pmemHeap,
                 uint32_t flags = IMemoryHeap::MAP_ONCE);
     ~MemoryHeapPmem();
@@ -51,11 +61,16 @@
     
     /* revoke all allocations made by this heap */
     virtual void revoke();
-    
+
+private:
+    /* use this to create your own IMemory for mapMemory */
+    virtual sp<MemoryPmem> createMemory(size_t offset, size_t size);
+    void remove(const wp<MemoryPmem>& memory);
+
 private:
     sp<MemoryHeapBase>              mParentHeap;
     mutable Mutex                   mLock;
-    Vector< wp<SubRegionMemory> >   mAllocations;
+    SortedVector< wp<MemoryPmem> >  mAllocations;
 };
 
 
diff --git a/include/utils/ResourceTypes.h b/include/utils/ResourceTypes.h
index 31b9aa8..2d56e3e 100644
--- a/include/utils/ResourceTypes.h
+++ b/include/utils/ResourceTypes.h
@@ -140,8 +140,6 @@
     void serialize(void* outData);
     // Deserialize/Unmarshall the patch data
     static Res_png_9patch* deserialize(const void* data);
-    // Deserialize/Unmarshall the patch data into a newly malloc-ed block
-    static void deserialize(const void* data, Res_png_9patch* outData);
     // Compute the size of the serialized data structure
     size_t serializedSize();
 };
@@ -860,6 +858,7 @@
         KEYSHIDDEN_ANY = 0x0000,
         KEYSHIDDEN_NO = 0x0001,
         KEYSHIDDEN_YES = 0x0002,
+        KEYSHIDDEN_SOFT = 0x0003,
     };
     
     union {
@@ -989,11 +988,20 @@
         return diffs;
     }
     
-    // Return true if 'this' is more specific than 'o'.
+    // Return true if 'this' is more specific than 'o'.  Optionally, if
+    // 'requested' is null, then they will also be compared against the
+    // requested configuration and true will only be returned if 'this'
+    // is a better candidate than 'o' for the configuration.  This assumes that
+    // match() has already been used to remove any configurations that don't
+    // match the requested configuration at all; if they are not first filtered,
+    // non-matching results can be considered better than matching ones.
     inline bool
     isBetterThan(const ResTable_config& o, const ResTable_config* requested = NULL) const {
+        // The order of the following tests defines the importance of one
+        // configuration parameter over another.  Those tests first are more
+        // important, trumping any values in those following them.
         if (imsi != 0 && (!requested || requested->imsi != 0)) {
-            if (mcc != 0 && (!requested || requested->mcc!= 0)) {
+            if (mcc != 0 && (!requested || requested->mcc != 0)) {
                 if (o.mcc == 0) {
                     return true;
                 }
@@ -1034,9 +1042,24 @@
             }
         }
         if (input != 0 && (!requested || requested->input != 0)) {
-            if ((inputFlags&MASK_KEYSHIDDEN) != 0 && (!requested
-                                                      || (requested->inputFlags&MASK_KEYSHIDDEN) != 0)) {
-                if ((o.inputFlags&MASK_KEYSHIDDEN) == 0) {
+            const int keysHidden = inputFlags&MASK_KEYSHIDDEN;
+            const int reqKeysHidden = requested
+                    ? requested->inputFlags&MASK_KEYSHIDDEN : 0;
+            if (keysHidden != 0 && reqKeysHidden != 0) {
+                const int oKeysHidden = o.inputFlags&MASK_KEYSHIDDEN;
+                //LOGI("isBetterThan keysHidden: cur=%d, given=%d, config=%d\n",
+                //        keysHidden, oKeysHidden, reqKeysHidden);
+                if (oKeysHidden == 0) {
+                    //LOGI("Better because 0!");
+                    return true;
+                }
+                // For compatibility, we count KEYSHIDDEN_NO as being
+                // the same as KEYSHIDDEN_SOFT.  Here we disambiguate these
+                // may making an exact match more specific.
+                if (keysHidden == reqKeysHidden && oKeysHidden != reqKeysHidden) {
+                    // The current configuration is an exact match, and
+                    // the given one is not, so the current one is better.
+                    //LOGI("Better because other not same!");
                     return true;
                 }
             }
@@ -1078,7 +1101,8 @@
         return false;
     }
     
-    // Return true if 'this' matches the parameters in 'settings'.
+    // Return true if 'this' can be considered a match for the parameters in
+    // 'settings'.
     inline bool match(const ResTable_config& settings) const {
         if (imsi != 0) {
             if (settings.mcc != 0 && mcc != 0
@@ -1121,7 +1145,14 @@
             const int setKeysHidden = settings.inputFlags&MASK_KEYSHIDDEN;
             if (setKeysHidden != 0 && keysHidden != 0
                 && keysHidden != setKeysHidden) {
-                return false;
+                // For compatibility, we count a request for KEYSHIDDEN_NO as also
+                // matching the more recent KEYSHIDDEN_SOFT.  Basically
+                // KEYSHIDDEN_NO means there is some kind of keyboard available.
+                //LOGI("Matching keysHidden: have=%d, config=%d\n", keysHidden, setKeysHidden);
+                if (keysHidden != KEYSHIDDEN_NO || setKeysHidden != KEYSHIDDEN_SOFT) {
+                    //LOGI("No match!");
+                    return false;
+                }
             }
             if (settings.keyboard != 0 && keyboard != 0
                 && keyboard != settings.keyboard) {
diff --git a/include/utils/TimeUtils.h b/include/utils/TimeUtils.h
index 30e5330..b19e021 100644
--- a/include/utils/TimeUtils.h
+++ b/include/utils/TimeUtils.h
@@ -17,10 +17,11 @@
 #ifndef ANDROID_TIME_H
 #define ANDROID_TIME_H
 
+#include <time.h>
+#include <cutils/tztime.h>
 #include <stdint.h>
 #include <sys/types.h>
 #include <sys/time.h>
-#include <time.h>
 #include <utils/String8.h>
 #include <utils/String16.h>
 
@@ -58,7 +59,7 @@
     Time();
 
     void switchTimezone(const char *timezone);
-    String8 format(const char *format) const;
+    String8 format(const char *format, const struct strftime_locale *locale) const;
     void format2445(short* buf, bool hasTime) const;
     String8 toString() const;
     void setToNow();
diff --git a/include/utils/string_array.h b/include/utils/string_array.h
index ede0644..064dda2 100644
--- a/include/utils/string_array.h
+++ b/include/utils/string_array.h
@@ -111,6 +111,19 @@
         return mArray[idx];
     }
 
+    //
+    // Set entry N to specified string.
+    // [should use operator[] here]
+    //
+    void setEntry(int idx, const char* str) {
+        if (idx < 0 || idx >= mCurrent)
+            return;
+        delete[] mArray[idx];
+        int len = strlen(str);
+        mArray[idx] = new char[len+1];
+        memcpy(mArray[idx], str, len+1);
+    }
+
 private:
     int     mMax;
     int     mCurrent;