merge in jb-release history after reset to jb-dev
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index dd015c6..880f81f 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -311,6 +311,8 @@
 
     ALOGI("begin\n");
 
+    signal(SIGPIPE, SIG_IGN);
+
     /* set as high priority, and protect from OOM killer */
     setpriority(PRIO_PROCESS, 0, -20);
     FILE *oom_adj = fopen("/proc/self/oom_adj", "w");
diff --git a/cmds/dumpsys/dumpsys.cpp b/cmds/dumpsys/dumpsys.cpp
index 7dad6b6..c9fcc00 100644
--- a/cmds/dumpsys/dumpsys.cpp
+++ b/cmds/dumpsys/dumpsys.cpp
@@ -28,6 +28,7 @@
 
 int main(int argc, char* const argv[])
 {
+    signal(SIGPIPE, SIG_IGN);
     sp<IServiceManager> sm = defaultServiceManager();
     fflush(stdout);
     if (sm == NULL) {
diff --git a/include/cpustats/ThreadCpuUsage.h b/include/cpustats/ThreadCpuUsage.h
index 9cd93d8..9756844 100644
--- a/include/cpustats/ThreadCpuUsage.h
+++ b/include/cpustats/ThreadCpuUsage.h
@@ -131,7 +131,8 @@
     uint32_t mCurrentkHz[MAX_CPU];  // current CPU frequency in kHz, not static to avoid a race
     static pthread_once_t sOnceControl;
     static int sKernelMax;          // like MAX_CPU, but determined at runtime == cpu/kernel_max + 1
-    static void init();
+    static void init();             // called once at first ThreadCpuUsage construction
+    static pthread_mutex_t sMutex;  // protects sScalingFds[] after initialization
 };
 
 }   // namespace android
diff --git a/include/ui/Rect.h b/include/ui/Rect.h
index 308da7b..c2c2675 100644
--- a/include/ui/Rect.h
+++ b/include/ui/Rect.h
@@ -65,15 +65,22 @@
     }
 
     // rectangle's width
-    inline int32_t width() const {
+    inline int32_t getWidth() const {
         return right-left;
     }
     
     // rectangle's height
-    inline int32_t height() const {
+    inline int32_t getHeight() const {
         return bottom-top;
     }
 
+    inline Rect getBounds() const {
+        return Rect(right-left, bottom-top);
+    }
+
+    inline int32_t width() const { return getWidth(); }
+    inline int32_t height() const { return getHeight(); }
+
     void setLeftTop(const Point& lt) {
         left = lt.x;
         top  = lt.y;
diff --git a/libs/cpustats/ThreadCpuUsage.cpp b/libs/cpustats/ThreadCpuUsage.cpp
index 99b4c83..637402a 100644
--- a/libs/cpustats/ThreadCpuUsage.cpp
+++ b/libs/cpustats/ThreadCpuUsage.cpp
@@ -165,6 +165,7 @@
 int ThreadCpuUsage::sScalingFds[ThreadCpuUsage::MAX_CPU];
 pthread_once_t ThreadCpuUsage::sOnceControl = PTHREAD_ONCE_INIT;
 int ThreadCpuUsage::sKernelMax;
+pthread_mutex_t ThreadCpuUsage::sMutex = PTHREAD_MUTEX_INITIALIZER;
 
 /*static*/
 void ThreadCpuUsage::init()
@@ -195,27 +196,10 @@
     } else {
         ALOGW("Can't open number of CPUs");
     }
-
-    // open fd to each frequency per CPU
-#define FREQ_SIZE 64
-    char freq_path[FREQ_SIZE];
-#define FREQ_DIGIT 27
-    COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
-    strlcpy(freq_path, "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq", sizeof(freq_path));
     int i;
     for (i = 0; i < MAX_CPU; ++i) {
         sScalingFds[i] = -1;
     }
-    for (i = 0; i < sKernelMax; ++i) {
-        freq_path[FREQ_DIGIT] = i + '0';
-        fd = open(freq_path, O_RDONLY);
-        if (fd >= 0) {
-            // keep this fd until process exit
-            sScalingFds[i] = fd;
-        } else {
-            ALOGW("Can't open CPU %d", i);
-        }
-    }
 }
 
 uint32_t ThreadCpuUsage::getCpukHz(int cpuNum)
@@ -224,10 +208,29 @@
         ALOGW("getCpukHz called with invalid CPU %d", cpuNum);
         return 0;
     }
+    // double-checked locking idiom is not broken for atomic values such as fd
     int fd = sScalingFds[cpuNum];
     if (fd < 0) {
-        ALOGW("getCpukHz called for unopened CPU %d", cpuNum);
-        return 0;
+        // some kernels can't open a scaling file until hot plug complete
+        pthread_mutex_lock(&sMutex);
+        fd = sScalingFds[cpuNum];
+        if (fd < 0) {
+#define FREQ_SIZE 64
+            char freq_path[FREQ_SIZE];
+#define FREQ_DIGIT 27
+            COMPILE_TIME_ASSERT_FUNCTION_SCOPE(MAX_CPU <= 10);
+#define FREQ_PATH "/sys/devices/system/cpu/cpu?/cpufreq/scaling_cur_freq"
+            strlcpy(freq_path, FREQ_PATH, sizeof(freq_path));
+            freq_path[FREQ_DIGIT] = cpuNum + '0';
+            fd = open(freq_path, O_RDONLY | O_CLOEXEC);
+            // keep this fd until process exit or exec
+            sScalingFds[cpuNum] = fd;
+        }
+        pthread_mutex_unlock(&sMutex);
+        if (fd < 0) {
+            ALOGW("getCpukHz can't open CPU %d", cpuNum);
+            return 0;
+        }
     }
 #define KHZ_SIZE 12
     char kHz[KHZ_SIZE];   // kHz base 10