Merge "Native: Sensor: For ndk sensor enable request, enable sensor with SENSOR_DELAY_NORMAL delay instead of 0 delay, by default " into nyc-dev
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index 87f637c..23954ea 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -42,6 +42,8 @@
 
 using namespace android;
 
+#define LOG_TAG "atrace"
+
 #define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
 
 enum { MAX_SYS_FILES = 10 };
@@ -769,6 +771,7 @@
 // Read the current kernel trace and write it to stdout.
 static void dumpTrace()
 {
+    ALOGE("Dumping trace");
     int traceFD = open(k_tracePath, O_RDWR);
     if (traceFD == -1) {
         fprintf(stderr, "error opening %s: %s (%d)\n", k_tracePath,
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index f0fb856..5898b41 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1058,7 +1058,9 @@
     }
 
     /* parse arguments */
-    log_args("Dumpstate command line", argc, const_cast<const char **>(argv));
+    std::string args;
+    format_args(argc, const_cast<const char **>(argv), &args);
+    MYLOGD("Dumpstate command line: %s\n", args.c_str());
     int c;
     while ((c = getopt(argc, argv, "dho:svqzpPBRV:")) != -1) {
         switch (c) {
diff --git a/cmds/dumpstate/dumpstate.h b/cmds/dumpstate/dumpstate.h
index 9c975d2..288fe39 100644
--- a/cmds/dumpstate/dumpstate.h
+++ b/cmds/dumpstate/dumpstate.h
@@ -171,8 +171,8 @@
 /* dump eMMC Extended CSD data */
 void dump_emmc_ecsd(const char *ext_csd_path);
 
-/** logs command-line arguments */
-void log_args(const std::string& message, int argc, const char *argv[]);
+/** gets command-line arguments */
+void format_args(int argc, const char *argv[], std::string *args);
 
 /*
  * Helper class used to report how long it takes for a section to finish.
diff --git a/cmds/dumpstate/utils.cpp b/cmds/dumpstate/utils.cpp
index 884f250..f0feb8e 100644
--- a/cmds/dumpstate/utils.cpp
+++ b/cmds/dumpstate/utils.cpp
@@ -607,6 +607,9 @@
     return true;
 }
 
+// TODO: refactor all those commands that convert args
+void format_args(const char* command, const char *args[], std::string *string);
+
 int run_command(const char *title, int timeout_seconds, const char *command, ...) {
     DurationReporter duration_reporter(title);
     fflush(stdout);
@@ -616,13 +619,24 @@
     va_list ap;
     va_start(ap, command);
     if (title) printf("------ %s (%s", title, command);
+    bool null_terminated = false;
     for (arg = 1; arg < sizeof(args) / sizeof(args[0]); ++arg) {
         args[arg] = va_arg(ap, const char *);
-        if (args[arg] == NULL) break;
+        if (args[arg] == nullptr) {
+            null_terminated = true;
+            break;
+        }
         if (title) printf(" %s", args[arg]);
     }
     if (title) printf(") ------\n");
     fflush(stdout);
+    if (!null_terminated) {
+        // Fail now, otherwise execvp() call on run_command_always() might hang.
+        std::string cmd;
+        format_args(command, args, &cmd);
+        MYLOGE("skipping command %s because its args were not NULL-terminated", cmd.c_str());
+        return -1;
+    }
 
     ON_DRY_RUN({ update_progress(timeout_seconds); va_end(ap); return 0; });
 
@@ -661,31 +675,43 @@
         sigaction(SIGPIPE, &sigact, NULL);
 
         execvp(command, (char**) args);
-        printf("*** exec(%s): %s\n", command, strerror(errno));
-        fflush(stdout);
-        _exit(-1);
+        // execvp's result will be handled after waitpid_with_timeout() below...
+        _exit(-1); // ...but it doesn't hurt to force exit, just in case
     }
 
     /* handle parent case */
     int status;
     bool ret = waitpid_with_timeout(pid, timeout_seconds, &status);
     uint64_t elapsed = DurationReporter::nanotime() - start;
+    std::string cmd; // used to log command and its args
     if (!ret) {
         if (errno == ETIMEDOUT) {
-            printf("*** %s: Timed out after %.3fs (killing pid %d)\n", command,
+            format_args(command, args, &cmd);
+            printf("*** command '%s' timed out after %.3fs (killing pid %d)\n", cmd.c_str(),
+                   (float) elapsed / NANOS_PER_SEC, pid);
+            MYLOGE("command '%s' timed out after %.3fs (killing pid %d)\n", cmd.c_str(),
                    (float) elapsed / NANOS_PER_SEC, pid);
         } else {
-            printf("*** %s: Error after %.4fs (killing pid %d)\n", command,
+            format_args(command, args, &cmd);
+            printf("*** command '%s': Error after %.4fs (killing pid %d)\n", cmd.c_str(),
+                   (float) elapsed / NANOS_PER_SEC, pid);
+            MYLOGE("command '%s': Error after %.4fs (killing pid %d)\n", cmd.c_str(),
                    (float) elapsed / NANOS_PER_SEC, pid);
         }
         kill(pid, SIGTERM);
         if (!waitpid_with_timeout(pid, 5, NULL)) {
             kill(pid, SIGKILL);
             if (!waitpid_with_timeout(pid, 5, NULL)) {
-                printf("*** %s: Cannot kill %d even with SIGKILL.\n", command, pid);
+                printf("couldn not kill command '%s' (pid %d) even with SIGKILL.\n", command, pid);
+                MYLOGE("couldn not kill command '%s' (pid %d) even with SIGKILL.\n", command, pid);
             }
         }
         return -1;
+    } else if (status) {
+        format_args(command, args, &cmd);
+        printf("*** command '%s' failed: %s\n", cmd.c_str(), strerror(errno));
+        MYLOGE("command '%s' failed: %s\n", cmd.c_str(), strerror(errno));
+        return -2;
     }
 
     if (WIFSIGNALED(status)) {
@@ -713,7 +739,9 @@
     }
     // Always terminate with NULL.
     am_args[am_index + 1] = NULL;
-    log_args("send_broadcast arguments", am_index, am_args);
+    std::string args_string;
+    format_args(am_index + 1, am_args, &args_string);
+    MYLOGD("send_broadcast command: %s\n", args_string.c_str());
     run_command_always(NULL, 5, am_args);
 }
 
@@ -1194,11 +1222,28 @@
     printf("\n");
 }
 
-void log_args(const std::string& message, int argc, const char *argv[]) {
-    std::string args;
+// TODO: refactor all those commands that convert args
+void format_args(int argc, const char *argv[], std::string *args) {
+    LOG_ALWAYS_FATAL_IF(args == nullptr);
     for (int i = 0; i < argc; i++) {
-        args.append(argv[i]);
-        args.append(" ");
+        args->append(argv[i]);
+        if (i < argc -1) {
+          args->append(" ");
+        }
     }
-    MYLOGD("%s: %s\n", message.c_str(), args.c_str());
+}
+void format_args(const char* command, const char *args[], std::string *string) {
+    LOG_ALWAYS_FATAL_IF(args == nullptr || command == nullptr);
+    string->append(command);
+    if (args[0] == nullptr) return;
+    string->append(" ");
+
+    for (int arg = 1; arg <= 1000; ++arg) {
+        if (args[arg] == nullptr) return;
+        string->append(args[arg]);
+        if (args[arg+1] != nullptr) {
+            string->append(" ");
+        }
+    }
+    MYLOGE("internal error: missing NULL entry on %s", string->c_str());
 }
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index 15c1036..77bcfc2 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -826,7 +826,9 @@
         strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
         have_dex2oat_compiler_filter_flag = true;
     } else if (extract_only) {
-        strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=verify-at-runtime");
+        // Temporarily make extract-only mean interpret-only, so extracted files will be verified.
+        // b/26833007
+        strcpy(dex2oat_compiler_filter_arg, "--compiler-filter=interpret-only");
         have_dex2oat_compiler_filter_flag = true;
     } else if (have_dex2oat_compiler_filter_flag) {
         sprintf(dex2oat_compiler_filter_arg, "--compiler-filter=%s", dex2oat_compiler_filter_flag);
diff --git a/cmds/installd/file_parsing.h b/cmds/installd/file_parsing.h
new file mode 100644
index 0000000..3e2f815
--- /dev/null
+++ b/cmds/installd/file_parsing.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2016 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.
+ */
+
+#ifndef OTAPREOPT_FILE_PARSING_H_
+#define OTAPREOPT_FILE_PARSING_H_
+
+#include <fstream>
+#include <functional>
+#include <string>
+
+namespace android {
+namespace installd {
+
+bool ParseFile(const std::string& strFile, std::function<bool (const std::string&)> parse) {
+    std::ifstream input_stream(strFile);
+
+    if (!input_stream.is_open()) {
+        return false;
+    }
+
+    while (!input_stream.eof()) {
+        // Read the next line.
+        std::string line;
+        getline(input_stream, line);
+
+        // Is the line empty? Simplifies the next check.
+        if (line.empty()) {
+            continue;
+        }
+
+        // Is this a comment (starts with pound)?
+        if (line[0] == '#') {
+            continue;
+        }
+
+        if (!parse(line)) {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+}  // namespace installd
+}  // namespace android
+
+#endif  // OTAPREOPT_FILE_PARSING_H_
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 3aac48b..89a4225 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <inttypes.h>
 #include <random>
+#include <regex>
 #include <selinux/android.h>
 #include <selinux/avc.h>
 #include <stdlib.h>
@@ -35,6 +36,7 @@
 #include <private/android_filesystem_config.h>
 
 #include <commands.h>
+#include <file_parsing.h>
 #include <globals.h>
 #include <installd_deps.h>  // Need to fill in requirements of commands.
 #include <string_helpers.h>
@@ -54,8 +56,8 @@
 namespace android {
 namespace installd {
 
-static constexpr const char* kBootClassPathPropertyName = "env.BOOTCLASSPATH";
-static constexpr const char* kAndroidRootPathPropertyName = "env.ANDROID_ROOT";
+static constexpr const char* kBootClassPathPropertyName = "BOOTCLASSPATH";
+static constexpr const char* kAndroidRootPathPropertyName = "ANDROID_ROOT";
 static constexpr const char* kOTARootDirectory = "/system-b";
 static constexpr size_t kISAIndex = 3;
 
@@ -131,41 +133,55 @@
 
 private:
     bool ReadSystemProperties() {
-        // TODO(agampe): What to do about the things in default.prop? It's only heap sizes, so it's easy
-        //               to emulate for now, but has issues (e.g., vendors modifying the boot classpath
-        //               may require larger values here - revisit). That's why this goes first, so that
-        //               if those dummy values are overridden in build.prop, that's what we'll get.
-        //
-        // Note: It seems we'll get access to the B root partition, so we should read the default.prop
-        //       file.
-        // if (!system_properties_.Load(b_mount_path_ + "/default.prop") {
-        //   return false;
-        // }
-        system_properties_.SetProperty("dalvik.vm.image-dex2oat-Xms", "64m");
-        system_properties_.SetProperty("dalvik.vm.image-dex2oat-Xmx", "64m");
-        system_properties_.SetProperty("dalvik.vm.dex2oat-Xms", "64m");
-        system_properties_.SetProperty("dalvik.vm.dex2oat-Xmx", "512m");
+        static constexpr const char* kPropertyFiles[] = {
+                "/default.prop", "/system/build.prop"
+        };
 
-        // TODO(agampe): Do this properly/test.
-        return system_properties_.Load(b_mount_path_ + "/system/build.prop");
+        for (size_t i = 0; i < arraysize(kPropertyFiles); ++i) {
+            if (!system_properties_.Load(kPropertyFiles[i])) {
+                return false;
+            }
+        }
+
+        return true;
     }
 
     bool ReadEnvironment() {
-        // Read important environment variables. For simplicity, store them as
-        // system properties.
-        // TODO(agampe): We'll have to parse init.environ.rc for BOOTCLASSPATH.
-        //               For now, just the A version.
-        const char* boot_classpath = getenv("BOOTCLASSPATH");
-        if (boot_classpath == nullptr) {
-            return false;
-        }
-        system_properties_.SetProperty(kBootClassPathPropertyName, boot_classpath);
+        // Parse the environment variables from init.environ.rc, which have the form
+        //   export NAME VALUE
+        // For simplicity, don't respect string quotation. The values we are interested in can be
+        // encoded without them.
+        std::regex export_regex("\\s*export\\s+(\\S+)\\s+(\\S+)");
+        bool parse_result = ParseFile("/init.environ.rc", [&](const std::string& line) {
+            std::smatch export_match;
+            if (!std::regex_match(line, export_match, export_regex)) {
+                return true;
+            }
 
-        const char* root_path = getenv("ANDROID_ROOT");
-        if (root_path == nullptr) {
+            if (export_match.size() != 3) {
+                return true;
+            }
+
+            std::string name = export_match[1].str();
+            std::string value = export_match[2].str();
+
+            system_properties_.SetProperty(name, value);
+
+            return true;
+        });
+        if (!parse_result) {
             return false;
         }
-        system_properties_.SetProperty(kAndroidRootPathPropertyName, b_mount_path_ + root_path);
+
+        // Check that we found important properties.
+        constexpr const char* kRequiredProperties[] = {
+                kBootClassPathPropertyName, kAndroidRootPathPropertyName
+        };
+        for (size_t i = 0; i < arraysize(kRequiredProperties); ++i) {
+            if (system_properties_.GetProperty(kRequiredProperties[i]) == nullptr) {
+                return false;
+            }
+        }
 
         return true;
     }
@@ -239,9 +255,7 @@
         // TODO: Delete files, just for a blank slate.
         const std::string& boot_cp = *system_properties_.GetProperty(kBootClassPathPropertyName);
 
-        std::string preopted_boot_art_path = StringPrintf("%s/system/framework/%s/boot.art",
-                                                          b_mount_path_.c_str(),
-                                                          isa);
+        std::string preopted_boot_art_path = StringPrintf("/system/framework/%s/boot.art", isa);
         if (access(preopted_boot_art_path.c_str(), F_OK) == 0) {
           return PatchoatBootImage(art_path, isa);
         } else {
@@ -254,7 +268,7 @@
         // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
 
         std::vector<std::string> cmd;
-        cmd.push_back(b_mount_path_ + "/system/bin/patchoat");
+        cmd.push_back("/system/bin/patchoat");
 
         cmd.push_back("--input-image-location=/system/framework/boot.art");
         cmd.push_back(StringPrintf("--output-image-file=%s", art_path.c_str()));
@@ -279,7 +293,7 @@
                           const char* isa) {
         // This needs to be kept in sync with ART, see art/runtime/gc/space/image_space.cc.
         std::vector<std::string> cmd;
-        cmd.push_back(b_mount_path_ + "/system/bin/dex2oat");
+        cmd.push_back("/system/bin/dex2oat");
         cmd.push_back(StringPrintf("--image=%s", art_path.c_str()));
         for (const std::string& boot_part : Split(boot_cp, ':')) {
             cmd.push_back(StringPrintf("--dex-file=%s", boot_part.c_str()));
@@ -305,8 +319,7 @@
                 "--compiler-filter=",
                 false,
                 cmd);
-        cmd.push_back(StringPrintf("--image-classes=%s/system/etc/preloaded-classes",
-                                   b_mount_path_.c_str()));
+        cmd.push_back("--image-classes=/system/etc/preloaded-classes");
         // TODO: Compiled-classes.
         const std::string* extra_opts =
                 system_properties_.GetProperty("dalvik.vm.image-dex2oat-flags");
@@ -468,10 +481,6 @@
         }
     }
 
-    // The path where the B partitions are mounted.
-    // TODO(agampe): If we're running this *inside* the change-root, we wouldn't need this.
-    std::string b_mount_path_;
-
     // Stores the system properties read out of the B partition. We need to use these properties
     // to compile, instead of the A properties we could get from init/get_property.
     SystemProperties system_properties_;
diff --git a/cmds/installd/system_properties.h b/cmds/installd/system_properties.h
index 1b5fb3a..2d940a3 100644
--- a/cmds/installd/system_properties.h
+++ b/cmds/installd/system_properties.h
@@ -21,6 +21,8 @@
 #include <string>
 #include <unordered_map>
 
+#include <file_parsing.h>
+
 namespace android {
 namespace installd {
 
@@ -28,31 +30,11 @@
 class SystemProperties {
  public:
     bool Load(const std::string& strFile) {
-        std::ifstream input_stream(strFile);
-
-        if (!input_stream.is_open()) {
-            return false;
-        }
-
-        while (!input_stream.eof()) {
-            // Read the next line.
-            std::string line;
-            getline(input_stream, line);
-
-            // Is the line empty? Simplifies the next check.
-            if (line.empty()) {
-                continue;
-            }
-
-            // Is this a comment (starts with pound)?
-            if (line[0] == '#') {
-                continue;
-            }
-
+        return ParseFile(strFile, [&](const std::string& line) {
             size_t equals_pos = line.find('=');
             if (equals_pos == std::string::npos || equals_pos == 0) {
                 // Did not find equals sign, or it's the first character - isn't a valid line.
-                continue;
+                return true;
             }
 
             std::string key = line.substr(0, equals_pos);
@@ -60,9 +42,9 @@
                                             line.length() - equals_pos + 1);
 
             properties_.insert(std::make_pair(key, value));
-        }
 
-        return true;
+            return true;
+        });
     }
 
     // Look up the key in the map. Returns null if the key isn't mapped.
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 794a7e5..e7703d8 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1196,8 +1196,10 @@
     egl_surface_t const * const s = get_surface(surface);
 
     if (attribute == EGL_FRONT_BUFFER_AUTO_REFRESH_ANDROID) {
-        return (native_window_set_auto_refresh(s->win.get(),
-                value ? true : false)) ? EGL_TRUE : EGL_FALSE;
+        int err = native_window_set_auto_refresh(s->win.get(),
+            value ? true : false);
+        return (err == NO_ERROR) ? EGL_TRUE :
+            setError(EGL_BAD_SURFACE, EGL_FALSE);
     }
 
     if (s->cnx->egl.eglSurfaceAttrib) {
diff --git a/vulkan/libvulkan/loader.cpp b/vulkan/libvulkan/loader.cpp
index d5cc280..eba58c6 100644
--- a/vulkan/libvulkan/loader.cpp
+++ b/vulkan/libvulkan/loader.cpp
@@ -265,6 +265,7 @@
 
     const VkAllocationCallbacks* alloc;
     uint32_t num_physical_devices;
+    VkPhysicalDevice physical_devices_top[kMaxPhysicalDevices];
     VkPhysicalDevice physical_devices[kMaxPhysicalDevices];
     DeviceExtensionSet physical_device_driver_extensions[kMaxPhysicalDevices];
 
@@ -1086,7 +1087,7 @@
         ALOGV("  no layer");
         Instance& instance = GetDispatchParent(gpu);
         size_t gpu_idx = 0;
-        while (instance.physical_devices[gpu_idx] != gpu)
+        while (instance.physical_devices_top[gpu_idx] != gpu)
             gpu_idx++;
         const DeviceExtensionSet driver_extensions =
             instance.physical_device_driver_extensions[gpu_idx];
@@ -1253,6 +1254,24 @@
         DestroyInstance(instance, allocator);
         return VK_ERROR_INITIALIZATION_FAILED;
     }
+
+    // Capture the physical devices from the top of the
+    // chain in case it has been wrapped by a layer.
+    uint32_t num_physical_devices = 0;
+    result = instance_dispatch.EnumeratePhysicalDevices(
+        local_instance, &num_physical_devices, nullptr);
+    if (result != VK_SUCCESS) {
+        DestroyInstance(instance, allocator);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
+    num_physical_devices = std::min(num_physical_devices, kMaxPhysicalDevices);
+    result = instance_dispatch.EnumeratePhysicalDevices(
+        local_instance, &num_physical_devices,
+        instance->physical_devices_top);
+    if (result != VK_SUCCESS) {
+        DestroyInstance(instance, allocator);
+        return VK_ERROR_INITIALIZATION_FAILED;
+    }
     *instance_out = local_instance;
 
     if (enable_callback) {
@@ -1342,10 +1361,6 @@
         return result;
     }
 
-    size_t gpu_idx = 0;
-    while (instance.physical_devices[gpu_idx] != gpu)
-        gpu_idx++;
-
     uint32_t activated_layers = 0;
     VkLayerDeviceCreateInfo chain_info;
     VkLayerDeviceLink* layer_device_link_info = nullptr;