Merge "init.rc: add class_start early_hal" into oc-dev
diff --git a/debuggerd/client/debuggerd_client.cpp b/debuggerd/client/debuggerd_client.cpp
index 224444f..3b84853 100644
--- a/debuggerd/client/debuggerd_client.cpp
+++ b/debuggerd/client/debuggerd_client.cpp
@@ -58,28 +58,31 @@
 }
 
 bool debuggerd_trigger_dump(pid_t pid, unique_fd output_fd, DebuggerdDumpType dump_type,
-                            int timeout_ms) {
+                            unsigned int timeout_ms) {
   LOG(INFO) << "libdebuggerd_client: started dumping process " << pid;
   unique_fd sockfd;
   const auto end = std::chrono::steady_clock::now() + std::chrono::milliseconds(timeout_ms);
-  auto time_left = [timeout_ms, &end]() { return end - std::chrono::steady_clock::now(); };
+  auto time_left = [&end]() { return end - std::chrono::steady_clock::now(); };
   auto set_timeout = [timeout_ms, &time_left](int sockfd) {
     if (timeout_ms <= 0) {
-      return -1;
+      return sockfd;
     }
 
     auto remaining = time_left();
     if (remaining < decltype(remaining)::zero()) {
-      LOG(ERROR) << "timeout expired";
+      LOG(ERROR) << "libdebuggerd_client: timeout expired";
       return -1;
     }
+
     struct timeval timeout;
     populate_timeval(&timeout, remaining);
 
     if (setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) != 0) {
+      PLOG(ERROR) << "libdebuggerd_client: failed to set receive timeout";
       return -1;
     }
     if (setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) != 0) {
+      PLOG(ERROR) << "libdebuggerd_client: failed to set send timeout";
       return -1;
     }
 
@@ -158,8 +161,10 @@
 
   // Forward output from the pipe to the output fd.
   while (true) {
-    auto remaining_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_left());
-    if (remaining_ms <= 1ms) {
+    auto remaining_ms = std::chrono::duration_cast<std::chrono::milliseconds>(time_left()).count();
+    if (timeout_ms <= 0) {
+      remaining_ms = -1;
+    } else if (remaining_ms < 0) {
       LOG(ERROR) << "libdebuggerd_client: timeout expired";
       return false;
     }
@@ -168,7 +173,7 @@
         .fd = pipe_read.get(), .events = POLLIN, .revents = 0,
     };
 
-    rc = poll(&pfd, 1, remaining_ms.count());
+    rc = poll(&pfd, 1, remaining_ms);
     if (rc == -1) {
       if (errno == EINTR) {
         continue;
diff --git a/debuggerd/client/debuggerd_client_test.cpp b/debuggerd/client/debuggerd_client_test.cpp
index 86d0314..aff03e5 100644
--- a/debuggerd/client/debuggerd_client_test.cpp
+++ b/debuggerd/client/debuggerd_client_test.cpp
@@ -89,3 +89,23 @@
 
   EXPECT_EQ(1, found_end) << "\nOutput: \n" << result;
 }
+
+TEST(debuggerd_client, no_timeout) {
+  unique_fd pipe_read, pipe_write;
+  ASSERT_TRUE(Pipe(&pipe_read, &pipe_write));
+
+  pid_t forkpid = fork();
+  ASSERT_NE(-1, forkpid);
+  if (forkpid == 0) {
+    pipe_write.reset();
+    char dummy;
+    TEMP_FAILURE_RETRY(read(pipe_read.get(), &dummy, sizeof(dummy)));
+    exit(0);
+  }
+
+  pipe_read.reset();
+
+  unique_fd output_read, output_write;
+  ASSERT_TRUE(Pipe(&output_read, &output_write));
+  ASSERT_TRUE(debuggerd_trigger_dump(forkpid, std::move(output_write), kDebuggerdBacktrace, 0));
+}
diff --git a/debuggerd/debuggerd_test.cpp b/debuggerd/debuggerd_test.cpp
index fa2838e..b705e27 100644
--- a/debuggerd/debuggerd_test.cpp
+++ b/debuggerd/debuggerd_test.cpp
@@ -500,9 +500,6 @@
 TEST(crash_dump, zombie) {
   pid_t forkpid = fork();
 
-  int pipefd[2];
-  ASSERT_EQ(0, pipe2(pipefd, O_CLOEXEC));
-
   pid_t rc;
   int status;
 
diff --git a/debuggerd/include/debuggerd/client.h b/debuggerd/include/debuggerd/client.h
index 91f143b..01de57b 100644
--- a/debuggerd/include/debuggerd/client.h
+++ b/debuggerd/include/debuggerd/client.h
@@ -28,9 +28,9 @@
 };
 
 // Trigger a dump of specified process to output_fd.
-// output_fd is *not* consumed, timeouts <= 0 will wait forever.
+// output_fd is consumed, timeout of 0 will wait forever.
 bool debuggerd_trigger_dump(pid_t pid, android::base::unique_fd output_fd,
-                            enum DebuggerdDumpType dump_type, int timeout_ms);
+                            enum DebuggerdDumpType dump_type, unsigned int timeout_ms);
 
 int dump_backtrace_to_file(pid_t tid, int fd);
 int dump_backtrace_to_file_timeout(pid_t tid, int fd, int timeout_secs);
diff --git a/libgrallocusage/GrallocUsageConversion.cpp b/libgrallocusage/GrallocUsageConversion.cpp
index 10e728d..8164beb 100644
--- a/libgrallocusage/GrallocUsageConversion.cpp
+++ b/libgrallocusage/GrallocUsageConversion.cpp
@@ -30,17 +30,13 @@
                                        /* ProducerUsage::CPU_WRITE_OFTEN | */
                                        ProducerUsage::GPU_RENDER_TARGET | ProducerUsage::PROTECTED |
                                        ProducerUsage::CAMERA | ProducerUsage::VIDEO_DECODER |
-                                       ProducerUsage::SENSOR_DIRECT_DATA |
-                                       /* Private flags may be consumer or producer */
-                                       GRALLOC_USAGE_PRIVATE_MASK;
+                                       ProducerUsage::SENSOR_DIRECT_DATA;
     constexpr uint64_t CONSUMER_MASK = ConsumerUsage::CPU_READ |
                                        /* ConsumerUsage::CPU_READ_OFTEN | */
                                        ConsumerUsage::GPU_TEXTURE | ConsumerUsage::HWCOMPOSER |
                                        ConsumerUsage::CLIENT_TARGET | ConsumerUsage::CURSOR |
                                        ConsumerUsage::VIDEO_ENCODER | ConsumerUsage::CAMERA |
-                                       ConsumerUsage::RENDERSCRIPT | ConsumerUsage::GPU_DATA_BUFFER |
-                                       /* Private flags may be consumer or producer */
-                                       GRALLOC_USAGE_PRIVATE_MASK;
+                                       ConsumerUsage::RENDERSCRIPT | ConsumerUsage::GPU_DATA_BUFFER;
     *producerUsage = static_cast<uint64_t>(usage) & PRODUCER_MASK;
     *consumerUsage = static_cast<uint64_t>(usage) & CONSUMER_MASK;
     if ((static_cast<uint32_t>(usage) & GRALLOC_USAGE_SW_READ_OFTEN) == GRALLOC_USAGE_SW_READ_OFTEN) {
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index bdbe725..8ef9328 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -1093,8 +1093,10 @@
         it = mLogElements.begin();
     } else {
         LogBufferElementCollection::iterator last;
-        // 30 second limit to continue search for out-of-order entries.
-        log_time min = start - log_time(30, 0);
+        // 3 second limit to continue search for out-of-order entries.
+        log_time min = start - log_time(3, 0);
+        // Cap to 300 iterations we look back for out-of-order entries.
+        size_t count = 300;
         // Client wants to start from some specified time. Chances are
         // we are better off starting from the end of the time sorted list.
         for (last = it = mLogElements.end(); it != mLogElements.begin();
@@ -1103,7 +1105,7 @@
             LogBufferElement* element = *it;
             if (element->getRealTime() > start) {
                 last = it;
-            } else if (element->getRealTime() < min) {
+            } else if (!--count || (element->getRealTime() < min)) {
                 break;
             }
         }
diff --git a/storaged/include/storaged.h b/storaged/include/storaged.h
index b6a0850..514798b 100644
--- a/storaged/include/storaged.h
+++ b/storaged/include/storaged.h
@@ -27,6 +27,7 @@
 #include <vector>
 
 #include <batteryservice/IBatteryPropertiesListener.h>
+#include <batteryservice/IBatteryPropertiesRegistrar.h>
 
 #include "storaged_info.h"
 #include "storaged_uid_monitor.h"
@@ -245,7 +246,8 @@
     int event_time_check_usec;  // check how much cputime spent in event loop
 };
 
-class storaged_t : public BnBatteryPropertiesListener {
+class storaged_t : public BnBatteryPropertiesListener,
+                   public IBinder::DeathRecipient {
 private:
     time_t mTimer;
     storaged_config mConfig;
@@ -253,6 +255,7 @@
     disk_stats_monitor mDsm;
     uid_monitor mUidm;
     time_t mStarttime;
+    sp<IBatteryPropertiesRegistrar> battery_properties;
 public:
     storaged_t(void);
     ~storaged_t() {}
@@ -281,6 +284,7 @@
 
     void init_battery_service();
     virtual void batteryPropertiesChanged(struct BatteryProperties props);
+    void binderDied(const wp<IBinder>& who);
 };
 
 // Eventlog tag
diff --git a/storaged/main.cpp b/storaged/main.cpp
index 2f2273d..4d1e430 100644
--- a/storaged/main.cpp
+++ b/storaged/main.cpp
@@ -42,11 +42,11 @@
 #include <storaged_service.h>
 #include <storaged_utils.h>
 
-storaged_t storaged;
+sp<storaged_t> storaged;
 
 // Function of storaged's main thread
-void* storaged_main(void* s) {
-    storaged_t* storaged = (storaged_t*)s;
+void* storaged_main(void* /* unused */) {
+    storaged = new storaged_t();
 
     storaged->init_battery_service();
 
@@ -116,7 +116,7 @@
         report_storage_health();
         // Start the main thread of storaged
         pthread_t storaged_main_thread;
-        errno = pthread_create(&storaged_main_thread, NULL, storaged_main, &storaged);
+        errno = pthread_create(&storaged_main_thread, NULL, storaged_main, NULL);
         if (errno != 0) {
             PLOG_TO(SYSTEM, ERROR) << "Failed to create main thread";
             return -1;
diff --git a/storaged/storaged.cpp b/storaged/storaged.cpp
index 1770922..54d429c 100644
--- a/storaged/storaged.cpp
+++ b/storaged/storaged.cpp
@@ -23,6 +23,7 @@
 #include <android-base/logging.h>
 #include <batteryservice/BatteryServiceConstants.h>
 #include <batteryservice/IBatteryPropertiesRegistrar.h>
+#include <binder/IPCThreadState.h>
 #include <binder/IServiceManager.h>
 #include <cutils/properties.h>
 #include <log/log.h>
@@ -173,7 +174,7 @@
     if (!mConfig.proc_uid_io_available)
         return;
 
-    sp<IBatteryPropertiesRegistrar> battery_properties = get_battery_properties_service();
+    battery_properties = get_battery_properties_service();
     if (battery_properties == NULL) {
         LOG_TO(SYSTEM, WARNING) << "failed to find batteryproperties service";
         return;
@@ -185,6 +186,18 @@
 
     // register listener after init uid_monitor
     battery_properties->registerListener(this);
+    IInterface::asBinder(battery_properties)->linkToDeath(this);
+}
+
+void storaged_t::binderDied(const wp<IBinder>& who) {
+    if (battery_properties != NULL &&
+        IInterface::asBinder(battery_properties) == who) {
+        LOG_TO(SYSTEM, ERROR) << "batteryproperties service died, exiting";
+        IPCThreadState::self()->stopProcess();
+        exit(1);
+    } else {
+        LOG_TO(SYSTEM, ERROR) << "unknown service died";
+    }
 }
 
 /* storaged_t */
diff --git a/storaged/storaged_service.cpp b/storaged/storaged_service.cpp
index 33e85e3..b1d3bfd 100644
--- a/storaged/storaged_service.cpp
+++ b/storaged/storaged_service.cpp
@@ -33,7 +33,7 @@
 
 using namespace android::base;
 
-extern storaged_t storaged;
+extern sp<storaged_t> storaged;
 
 std::vector<struct uid_info> BpStoraged::dump_uids(const char* /*option*/) {
     Parcel data, reply;
@@ -74,7 +74,7 @@
 
 std::vector<struct uid_info> Storaged::dump_uids(const char* /* option */) {
     std::vector<struct uid_info> uids_v;
-    std::unordered_map<uint32_t, struct uid_info> uids_m = storaged.get_uids();
+    std::unordered_map<uint32_t, struct uid_info> uids_m = storaged->get_uids();
 
     for (const auto& it : uids_m) {
         uids_v.push_back(it.second);
@@ -127,7 +127,7 @@
 
     uint64_t last_ts = 0;
     const std::map<uint64_t, struct uid_records>& records =
-                storaged.get_uid_records(hours, threshold, force_report);
+                storaged->get_uid_records(hours, threshold, force_report);
     for (const auto& it : records) {
         if (last_ts != it.second.start_ts) {
             dprintf(fd, "%llu", (unsigned long long)it.second.start_ts);
@@ -150,7 +150,7 @@
     }
 
     if (time_window) {
-        storaged.update_uid_io_interval(time_window);
+        storaged->update_uid_io_interval(time_window);
     }
 
     return NO_ERROR;