Merge "Fixed header on runCommand()."
diff --git a/cmds/atrace/Android.bp b/cmds/atrace/Android.bp
index 6bfb0a4..194a565 100644
--- a/cmds/atrace/Android.bp
+++ b/cmds/atrace/Android.bp
@@ -6,6 +6,7 @@
 
     shared_libs: [
         "libbinder",
+        "liblog",
         "libcutils",
         "libutils",
         "libz",
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index dc68d11..34eeb5f 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -35,9 +35,10 @@
 #include <sys/wait.h>
 #include <unistd.h>
 
+#include <android-base/file.h>
+#include <android-base/properties.h>
 #include <android-base/stringprintf.h>
 #include <android-base/unique_fd.h>
-#include <android-base/file.h>
 #include <cutils/properties.h>
 #include <hardware_legacy/power.h>
 
@@ -62,7 +63,7 @@
 
 // TODO: variables below should be part of dumpstate object
 static unsigned long id;
-static char build_type[PROPERTY_VALUE_MAX];
+static std::string buildType;
 static time_t now;
 static std::unique_ptr<ZipWriter> zip_writer;
 static std::set<std::string> mount_points;
@@ -71,8 +72,8 @@
 /* suffix of the bugreport files - it's typically the date (when invoked with -d),
  * although it could be changed by the user using a system property */
 static std::string suffix;
-static bool dry_run = false;
-static char extra_options[PROPERTY_VALUE_MAX];
+static bool dryRun = false;
+static std::string extraOptions;
 
 #define PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops"
 #define ALT_PSTORE_LAST_KMSG "/sys/fs/pstore/console-ramoops-0"
@@ -109,13 +110,14 @@
 static std::string VERSION_DEFAULT = "1.0";
 
 static constexpr char PROPERTY_EXTRA_OPTIONS[] = "dumpstate.options";
+static constexpr char PROPERTY_LAST_ID[] = "dumpstate.last_id";
 
 bool is_user_build() {
-    return 0 == strncmp(build_type, "user", PROPERTY_VALUE_MAX - 1);
+    return "user" == buildType;
 }
 
 bool is_dry_run() {
-    return dry_run;
+    return dryRun;
 }
 
 /* gets the tombstone data, according to the bugreport type: if zipped, gets all tombstones;
@@ -615,6 +617,7 @@
     return value <= maximum;
 }
 
+// TODO: migrate to logd/LogBuffer.cpp or use android::base::GetProperty
 static unsigned long property_get_size(const char *key) {
     unsigned long value;
     char *cp, property[PROPERTY_VALUE_MAX];
@@ -681,16 +684,15 @@
 
 /* dumps the current system state to stdout */
 static void print_header(std::string version) {
-    char build[PROPERTY_VALUE_MAX], fingerprint[PROPERTY_VALUE_MAX];
-    char radio[PROPERTY_VALUE_MAX], bootloader[PROPERTY_VALUE_MAX];
-    char network[PROPERTY_VALUE_MAX], date[80];
+    std::string build, fingerprint, radio, bootloader, network;
+    char date[80];
 
-    property_get("ro.build.display.id", build, "(unknown)");
-    property_get("ro.build.fingerprint", fingerprint, "(unknown)");
-    property_get("ro.build.type", build_type, "(unknown)");
-    property_get("gsm.version.baseband", radio, "(unknown)");
-    property_get("ro.bootloader", bootloader, "(unknown)");
-    property_get("gsm.operator.alpha", network, "(unknown)");
+    build = android::base::GetProperty("ro.build.display.id", "(unknown)");
+    fingerprint = android::base::GetProperty("ro.build.fingerprint", "(unknown)");
+    buildType = android::base::GetProperty("ro.build.type", "(unknown)");
+    radio = android::base::GetProperty("gsm.version.baseband", "(unknown)");
+    bootloader = android::base::GetProperty("ro.bootloader", "(unknown)");
+    network = android::base::GetProperty("gsm.operator.alpha", "(unknown)");
     strftime(date, sizeof(date), "%Y-%m-%d %H:%M:%S", localtime(&now));
 
     printf("========================================================\n");
@@ -698,18 +700,19 @@
     printf("========================================================\n");
 
     printf("\n");
-    printf("Build: %s\n", build);
-    printf("Build fingerprint: '%s'\n", fingerprint); /* format is important for other tools */
-    printf("Bootloader: %s\n", bootloader);
-    printf("Radio: %s\n", radio);
-    printf("Network: %s\n", network);
+    printf("Build: %s\n", build.c_str());
+    // NOTE: fingerprint entry format is important for other tools.
+    printf("Build fingerprint: '%s'\n", fingerprint.c_str());
+    printf("Bootloader: %s\n", bootloader.c_str());
+    printf("Radio: %s\n", radio.c_str());
+    printf("Network: %s\n", network.c_str());
 
     printf("Kernel: ");
     dumpFile(nullptr, "/proc/version");
     printf("Command line: %s\n", strtok(cmdline_buf, "\n"));
     printf("Bugreport format version: %s\n", version.c_str());
-    printf("Dumpstate info: id=%lu pid=%d dry_run=%d args=%s extra_options=%s\n", id, getpid(),
-           dry_run, args.c_str(), extra_options);
+    printf("Dumpstate info: id=%lu pid=%d dryRun=%d args=%s extraOptions=%s\n", id, getpid(),
+           dryRun, args.c_str(), extraOptions.c_str());
     printf("\n");
 }
 
@@ -928,34 +931,34 @@
 
     /* only show ANR traces if they're less than 15 minutes old */
     struct stat st;
-    char anr_traces_path[PATH_MAX];
-    property_get("dalvik.vm.stack-trace-file", anr_traces_path, "");
-    if (!anr_traces_path[0]) {
+    std::string anrTracesPath = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
+    if (anrTracesPath.empty()) {
         printf("*** NO VM TRACES FILE DEFINED (dalvik.vm.stack-trace-file)\n\n");
     } else {
-      int fd = TEMP_FAILURE_RETRY(open(anr_traces_path,
-                                       O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
-      if (fd < 0) {
-          printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anr_traces_path, strerror(errno));
+        int fd = TEMP_FAILURE_RETRY(
+            open(anrTracesPath.c_str(), O_RDONLY | O_CLOEXEC | O_NOFOLLOW | O_NONBLOCK));
+        if (fd < 0) {
+            printf("*** NO ANR VM TRACES FILE (%s): %s\n\n", anrTracesPath.c_str(), strerror(errno));
       } else {
-          dump_file_from_fd("VM TRACES AT LAST ANR", anr_traces_path, fd);
+          dump_file_from_fd("VM TRACES AT LAST ANR", anrTracesPath.c_str(), fd);
       }
     }
 
     /* slow traces for slow operations */
-    if (anr_traces_path[0] != 0) {
-        int tail = strlen(anr_traces_path)-1;
-        while (tail > 0 && anr_traces_path[tail] != '/') {
+    if (!anrTracesPath.empty()) {
+        int tail = anrTracesPath.size() - 1;
+        while (tail > 0 && anrTracesPath.at(tail) != '/') {
             tail--;
         }
         int i = 0;
         while (1) {
-            sprintf(anr_traces_path+tail+1, "slow%02d.txt", i);
-            if (stat(anr_traces_path, &st)) {
+            anrTracesPath =
+                anrTracesPath.substr(0, tail + 1) + android::base::StringPrintf("slow%02d.txt", i);
+            if (stat(anrTracesPath.c_str(), &st)) {
                 // No traces file at this index, done with the files.
                 break;
             }
-            dumpFile("VM TRACES WHEN SLOW", anr_traces_path);
+            dumpFile("VM TRACES WHEN SLOW", anrTracesPath.c_str());
             i++;
         }
     }
@@ -1081,14 +1084,13 @@
     }
 
     /* Migrate the ril_dumpstate to a dumpstate_board()? */
-    char ril_dumpstate_timeout[PROPERTY_VALUE_MAX] = {0};
-    property_get("ril.dumpstate.timeout", ril_dumpstate_timeout, "30");
-    if (strnlen(ril_dumpstate_timeout, PROPERTY_VALUE_MAX - 1) > 0) {
+    int rilDumpstateTimeout = android::base::GetIntProperty("ril.dumpstate.timeout", 0);
+    if (rilDumpstateTimeout > 0) {
         // su does not exist on user builds, so try running without it.
         // This way any implementations of vril-dump that do not require
         // root can run on user builds.
         CommandOptions::CommandOptionsBuilder options =
-            CommandOptions::WithTimeout(atoi(ril_dumpstate_timeout));
+            CommandOptions::WithTimeout(rilDumpstateTimeout);
         if (!is_user_build()) {
             options.AsRoot();
         }
@@ -1295,8 +1297,8 @@
         register_sig_handler();
     }
 
-    dry_run = property_get_bool("dumpstate.dry_run", 0) != 0;
-    if (is_dry_run()) {
+    dryRun = android::base::GetBoolProperty("dumpstate.dry_run", false);
+    if (dryRun) {
         MYLOGI("Running on dry-run mode (to disable it, call 'setprop dumpstate.dry_run false')\n");
     }
 
@@ -1308,15 +1310,13 @@
         }
     }
 
-    property_get(PROPERTY_EXTRA_OPTIONS, extra_options, "");
-    MYLOGI("Dumpstate args: %s (extra options: %s)\n", args.c_str(), extra_options);
+    extraOptions = android::base::GetProperty(PROPERTY_EXTRA_OPTIONS, "");
+    MYLOGI("Dumpstate args: %s (extra options: %s)\n", args.c_str(), extraOptions.c_str());
 
     /* gets the sequential id */
-    char last_id[PROPERTY_VALUE_MAX];
-    property_get("dumpstate.last_id", last_id, "0");
-    id = strtoul(last_id, NULL, 10) + 1;
-    snprintf(last_id, sizeof(last_id), "%lu", id);
-    property_set("dumpstate.last_id", last_id);
+    int lastId = android::base::GetIntProperty(PROPERTY_LAST_ID, 0);
+    id = ++lastId;
+    android::base::SetProperty(PROPERTY_LAST_ID, std::to_string(lastId));
     MYLOGI("dumpstate id: %lu\n", id);
 
     /* set as high priority, and protect from OOM killer */
@@ -1358,26 +1358,26 @@
         }
     }
 
-    if (strlen(extra_options) > 0) {
+    if (!extraOptions.empty()) {
         // Framework uses a system property to override some command-line args.
         // Currently, it contains the type of the requested bugreport.
-        if (strcmp(extra_options, "bugreportplus") == 0) {
+        if (extraOptions == "bugreportplus") {
             MYLOGD("Running as bugreportplus: add -P, remove -p\n");
             do_update_progress = 1;
             do_fb = 0;
-        } else if (strcmp(extra_options, "bugreportremote") == 0) {
+        } else if (extraOptions == "bugreportremote") {
             MYLOGD("Running as bugreportremote: add -q -R, remove -p\n");
             do_vibrate = 0;
             is_remote_mode = 1;
             do_fb = 0;
-        } else if (strcmp(extra_options, "bugreportwear") == 0) {
+        } else if (extraOptions == "bugreportwear") {
             MYLOGD("Running as bugreportwear: add -P\n");
             do_update_progress = 1;
         } else {
-            MYLOGE("Unknown extra option: %s\n", extra_options);
+            MYLOGE("Unknown extra option: %s\n", extraOptions.c_str());
         }
         // Reset the property
-        property_set(PROPERTY_EXTRA_OPTIONS, "");
+        android::base::SetProperty(PROPERTY_EXTRA_OPTIONS, "");
     }
 
     if ((do_zip_file || do_add_date || do_update_progress || do_broadcast) && !use_outfile) {
@@ -1455,9 +1455,8 @@
         } else {
             suffix = "undated";
         }
-        char build_id[PROPERTY_VALUE_MAX];
-        property_get("ro.build.id", build_id, "UNKNOWN_BUILD");
-        base_name = base_name + "-" + build_id;
+        std::string buildId = android::base::GetProperty("ro.build.id", "UNKNOWN_BUILD");
+        base_name = base_name + "-" + buildId;
         if (do_fb) {
             // TODO: if dumpstate was an object, the paths could be internal variables and then
             // we could have a function to calculate the derived values, such as:
@@ -1614,23 +1613,21 @@
     if (use_outfile) {
 
         /* check if user changed the suffix using system properties */
-        char key[PROPERTY_KEY_MAX];
-        char value[PROPERTY_VALUE_MAX];
-        snprintf(key, sizeof(key), "dumpstate.%d.name", getpid());
-        property_get(key, value, "");
+        std::string name = android::base::GetProperty(
+            android::base::StringPrintf("dumpstate.%d.name", getpid()), "");
         bool change_suffix= false;
-        if (value[0]) {
+        if (!name.empty()) {
             /* must whitelist which characters are allowed, otherwise it could cross directories */
             std::regex valid_regex("^[-_a-zA-Z0-9]+$");
-            if (std::regex_match(value, valid_regex)) {
+            if (std::regex_match(name.c_str(), valid_regex)) {
                 change_suffix = true;
             } else {
-                MYLOGE("invalid suffix provided by user: %s\n", value);
+                MYLOGE("invalid suffix provided by user: %s\n", name.c_str());
             }
         }
         if (change_suffix) {
-            MYLOGI("changing suffix from %s to %s\n", suffix.c_str(), value);
-            suffix = value;
+            MYLOGI("changing suffix from %s to %s\n", suffix.c_str(), name.c_str());
+            suffix = name;
             if (!screenshot_path.empty()) {
                 std::string new_screenshot_path =
                         bugreport_dir + "/" + base_name + "-" + suffix + ".png";
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 5e074d9..5575084 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -39,6 +39,7 @@
 #define LOG_TAG "dumpstate"
 
 #include <android-base/file.h>
+#include <android-base/properties.h>
 #include <cutils/debugger.h>
 #include <cutils/log.h>
 #include <cutils/properties.h>
@@ -1088,36 +1089,34 @@
 
 /* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
 const char *dump_traces() {
-    DurationReporter duration_reporter("DUMP TRACES", NULL);
-    if (is_dry_run()) return NULL;
+    DurationReporter duration_reporter("DUMP TRACES", nullptr);
+    if (is_dry_run()) return nullptr;
 
-    const char* result = NULL;
+    const char* result = nullptr;
 
-    char traces_path[PROPERTY_VALUE_MAX] = "";
-    property_get("dalvik.vm.stack-trace-file", traces_path, "");
-    if (!traces_path[0]) return NULL;
+    std::string tracesPath = android::base::GetProperty("dalvik.vm.stack-trace-file", "");
+    if (tracesPath.empty()) return nullptr;
 
     /* move the old traces.txt (if any) out of the way temporarily */
-    char anr_traces_path[PATH_MAX];
-    strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path));
-    strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path));
-    if (rename(traces_path, anr_traces_path) && errno != ENOENT) {
-        MYLOGE("rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno));
-        return NULL;  // Can't rename old traces.txt -- no permission? -- leave it alone instead
+    std::string anrTracesPath = tracesPath + ".anr";
+    if (rename(tracesPath.c_str(), anrTracesPath.c_str()) && errno != ENOENT) {
+        MYLOGE("rename(%s, %s): %s\n", tracesPath.c_str(), anrTracesPath.c_str(), strerror(errno));
+        return nullptr;  // Can't rename old traces.txt -- no permission? -- leave it alone instead
     }
 
     /* create a new, empty traces.txt file to receive stack dumps */
-    int fd = TEMP_FAILURE_RETRY(open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
-                                     0666));  /* -rw-rw-rw- */
+    int fd = TEMP_FAILURE_RETRY(open(tracesPath.c_str(),
+                                     O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW | O_CLOEXEC,
+                                     0666)); /* -rw-rw-rw- */
     if (fd < 0) {
-        MYLOGE("%s: %s\n", traces_path, strerror(errno));
-        return NULL;
+        MYLOGE("%s: %s\n", tracesPath.c_str(), strerror(errno));
+        return nullptr;
     }
     int chmod_ret = fchmod(fd, 0666);
     if (chmod_ret < 0) {
-        MYLOGE("fchmod on %s failed: %s\n", traces_path, strerror(errno));
+        MYLOGE("fchmod on %s failed: %s\n", tracesPath.c_str(), strerror(errno));
         close(fd);
-        return NULL;
+        return nullptr;
     }
 
     /* Variables below must be initialized before 'goto' statements */
@@ -1138,9 +1137,9 @@
         goto error_close_fd;
     }
 
-    wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE);
+    wfd = inotify_add_watch(ifd, tracesPath.c_str(), IN_CLOSE_WRITE);
     if (wfd < 0) {
-        MYLOGE("inotify_add_watch(%s): %s\n", traces_path, strerror(errno));
+        MYLOGE("inotify_add_watch(%s): %s\n", tracesPath.c_str(), strerror(errno));
         goto error_close_ifd;
     }
 
@@ -1224,17 +1223,15 @@
         MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
     }
 
-    static char dump_traces_path[PATH_MAX];
-    strlcpy(dump_traces_path, traces_path, sizeof(dump_traces_path));
-    strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path));
-    if (rename(traces_path, dump_traces_path)) {
-        MYLOGE("rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno));
+    static std::string dumpTracesPath = tracesPath + ".bugreport";
+    if (rename(tracesPath.c_str(), dumpTracesPath.c_str())) {
+        MYLOGE("rename(%s, %s): %s\n", tracesPath.c_str(), dumpTracesPath.c_str(), strerror(errno));
         goto error_close_ifd;
     }
-    result = dump_traces_path;
+    result = dumpTracesPath.c_str();
 
     /* replace the saved [ANR] traces.txt file */
-    rename(anr_traces_path, traces_path);
+    rename(anrTracesPath.c_str(), tracesPath.c_str());
 
 error_close_ifd:
     close(ifd);
diff --git a/libs/gui/tests/Android.mk b/libs/gui/tests/Android.mk
index 7d984a4..efae7f6 100644
--- a/libs/gui/tests/Android.mk
+++ b/libs/gui/tests/Android.mk
@@ -16,6 +16,7 @@
     GLTest.cpp \
     IGraphicBufferProducer_test.cpp \
     MultiTextureConsumer_test.cpp \
+    Sensor_test.cpp \
     SRGB_test.cpp \
     StreamSplitter_test.cpp \
     SurfaceTextureClient_test.cpp \
diff --git a/libs/gui/tests/Sensor_test.cpp b/libs/gui/tests/Sensor_test.cpp
new file mode 100644
index 0000000..fbf282d
--- /dev/null
+++ b/libs/gui/tests/Sensor_test.cpp
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "Sensor_test"
+
+#include <gui/Sensor.h>
+#include <hardware/sensors.h>
+#include <utils/Errors.h>
+
+#include <gtest/gtest.h>
+
+namespace android {
+
+// Returns true if the two sensors have the same attributes. Does not compare
+// UUID since that should not be transmitted via flatten/unflatten.
+static bool sensorsMatch(const Sensor& a, const Sensor& b) {
+    return a.getName() == b.getName () &&
+        a.getVendor() == b.getVendor () &&
+        a.getHandle() == b.getHandle () &&
+        a.getType() == b.getType () &&
+        a.getMinValue() == b.getMinValue () &&
+        a.getMaxValue() == b.getMaxValue () &&
+        a.getResolution() == b.getResolution () &&
+        a.getPowerUsage() == b.getPowerUsage () &&
+        a.getMinDelay() == b.getMinDelay () &&
+        a.getMinDelayNs() == b.getMinDelayNs () &&
+        a.getVersion() == b.getVersion () &&
+        a.getFifoReservedEventCount() == b.getFifoReservedEventCount () &&
+        a.getFifoMaxEventCount() == b.getFifoMaxEventCount () &&
+        a.getStringType() == b.getStringType () &&
+        a.getRequiredPermission() == b.getRequiredPermission () &&
+        a.isRequiredPermissionRuntime() == b.isRequiredPermissionRuntime () &&
+        a.getRequiredAppOp() == b.getRequiredAppOp () &&
+        a.getMaxDelay() == b.getMaxDelay () &&
+        a.getFlags() == b.getFlags () &&
+        a.isWakeUpSensor() == b.isWakeUpSensor () &&
+        a.isDynamicSensor() == b.isDynamicSensor () &&
+        a.hasAdditionalInfo() == b.hasAdditionalInfo () &&
+        a.getReportingMode() == b.getReportingMode();
+}
+
+// Creates and returns a sensor_t struct with some default values filled in.
+static sensor_t getTestSensorT() {
+    sensor_t hwSensor = {};
+    hwSensor.name = "Test Sensor";
+    hwSensor.vendor = "Test Vendor";
+    hwSensor.version = 1;
+    hwSensor.handle = 2;
+    hwSensor.type = SENSOR_TYPE_ACCELEROMETER;
+    hwSensor.maxRange = 10.f;
+    hwSensor.resolution = 1.f;
+    hwSensor.power = 5.f;
+    hwSensor.minDelay = 1000;
+    hwSensor.fifoReservedEventCount = 50;
+    hwSensor.fifoMaxEventCount = 100;
+    hwSensor.stringType = SENSOR_STRING_TYPE_ACCELEROMETER;
+    hwSensor.requiredPermission = "";
+    hwSensor.maxDelay = 5000;
+    hwSensor.flags = SENSOR_FLAG_CONTINUOUS_MODE;
+    return hwSensor;
+}
+
+TEST(SensorTest, FlattenAndUnflatten) {
+    sensor_t hwSensor = getTestSensorT();
+    Sensor sensor1(&hwSensor, SENSORS_DEVICE_API_VERSION_1_4);
+    Sensor sensor2;
+
+    std::vector<uint8_t> buffer(sensor1.getFlattenedSize());
+    ASSERT_EQ(OK, sensor1.flatten(buffer.data(), buffer.size()));
+    ASSERT_EQ(OK, sensor2.unflatten(buffer.data(), buffer.size()));
+
+    EXPECT_TRUE(sensorsMatch(sensor1, sensor2));
+}
+
+} // namespace android