Merge "Fix Parcelable::readParcelableVector<T>" into nyc-dev
diff --git a/cmds/installd/commands.cpp b/cmds/installd/commands.cpp
index c0c91da..2a9950a 100644
--- a/cmds/installd/commands.cpp
+++ b/cmds/installd/commands.cpp
@@ -1208,50 +1208,50 @@
 
 static void run_profman_dump(const std::vector<fd_t>& profile_fds,
                              fd_t reference_profile_fd,
-                             const std::vector<std::string>& code_locations,
-                             const std::vector<fd_t>& code_location_fds,
+                             const std::vector<std::string>& dex_locations,
+                             const std::vector<fd_t>& apk_fds,
                              fd_t output_fd) {
+    std::vector<std::string> profman_args;
     static const char* PROFMAN_BIN = "/system/bin/profman";
-    const bool has_reference_profile = (reference_profile_fd != -1);
-    // program name
-    // --dump-only
-    // --dump-output-to-fd=<output_fd>
-    // (optionally, --reference-profile-file-fd=<reference_profile_fd>)
-    const size_t fixed_args = (has_reference_profile ? 4 : 3);
-    // Fixed arguments, profiles, code paths, code path fds, and final NULL.
-    const size_t argc = fixed_args + profile_fds.size() + code_locations.size() +
-        code_location_fds.size() + 1;
-    const char **argv = new const char*[argc];
-    int i = 0;
-    argv[i++] = PROFMAN_BIN;
-    argv[i++] = "--dump-only";
-    std::string dump_output = StringPrintf("--dump-output-to-fd=%d", output_fd);
-    argv[i++] = dump_output.c_str();
-    if (has_reference_profile) {
-        std::string reference =
-            StringPrintf("--reference-profile-file-fd=%d", reference_profile_fd);
-        argv[i++] = reference.c_str();
+    profman_args.push_back(PROFMAN_BIN);
+    profman_args.push_back("--dump-only");
+    profman_args.push_back(StringPrintf("--dump-output-to-fd=%d", output_fd));
+    if (reference_profile_fd != -1) {
+        profman_args.push_back(StringPrintf("--reference-profile-file-fd=%d",
+                                            reference_profile_fd));
     }
     for (fd_t profile_fd : profile_fds) {
-        std::string profile_arg = StringPrintf("--profile-file-fd=%d", profile_fd);
-        argv[i++] = strdup(profile_arg.c_str());
+        profman_args.push_back(StringPrintf("--profile-file-fd=%d", profile_fd));
     }
-    for (const std::string& code_location : code_locations) {
-        std::string path_str = StringPrintf("--code-location=%s", code_location.c_str());
-        argv[i++] = strdup(path_str.c_str());
+    for (const std::string& dex_location : dex_locations) {
+        profman_args.push_back(StringPrintf("--dex-location=%s", dex_location.c_str()));
     }
-    for (fd_t code_location_fd : code_location_fds) {
-        std::string fd_str = StringPrintf("--code-location-fd=%d", code_location_fd);
-        argv[i++] = strdup(fd_str.c_str());
+    for (fd_t apk_fd : apk_fds) {
+        profman_args.push_back(StringPrintf("--apk-fd=%d", apk_fd));
+    }
+    const char **argv = new const char*[profman_args.size() + 1];
+    size_t i = 0;
+    for (const std::string& profman_arg : profman_args) {
+        argv[i++] = profman_arg.c_str();
     }
     argv[i] = NULL;
-    assert(i == argc - 1);
 
     execv(PROFMAN_BIN, (char * const *)argv);
     ALOGE("execv(%s) failed: %s\n", PROFMAN_BIN, strerror(errno));
     exit(68);   /* only get here on exec failure */
 }
 
+static const char* get_location_from_path(const char* path) {
+    static constexpr char kLocationSeparator = '/';
+    const char *location = strrchr(path, kLocationSeparator);
+    if (location == NULL) {
+        return path;
+    } else {
+        // Skip the separator character.
+        return location + 1;
+    }
+}
+
 // Dumps the contents of a profile file, using pkgname's dex files for pretty
 // printing the result.
 bool dump_profile(uid_t uid, const char* pkgname, const char* code_path_string) {
@@ -1271,32 +1271,35 @@
         return false;
     }
 
-    fd_t output_fd = open(out_file_name.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW);
+    fd_t output_fd = open(out_file_name.c_str(), O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW);
     if (fchmod(output_fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) {
         ALOGE("installd cannot chmod '%s' dump_profile\n", out_file_name.c_str());
         return false;
     }
-    std::vector<std::string> code_locations = base::Split(code_path_string, ";");
-    std::vector<fd_t> code_location_fds;
-    for (const std::string& code_location : code_locations) {
-        fd_t code_location_fd = open(code_location.c_str(), O_RDONLY | O_NOFOLLOW);
-        if (code_location_fd == -1) {
-            ALOGE("installd cannot open '%s'\n", code_location.c_str());
+    std::vector<std::string> code_full_paths = base::Split(code_path_string, ";");
+    std::vector<std::string> dex_locations;
+    std::vector<fd_t> apk_fds;
+    for (const std::string& code_full_path : code_full_paths) {
+        const char* full_path = code_full_path.c_str();
+        fd_t apk_fd = open(full_path, O_RDONLY | O_NOFOLLOW);
+        if (apk_fd == -1) {
+            ALOGE("installd cannot open '%s'\n", full_path);
             return false;
         }
-        code_location_fds.push_back(code_location_fd);
+        dex_locations.push_back(get_location_from_path(full_path));
+        apk_fds.push_back(apk_fd);
     }
 
     pid_t pid = fork();
     if (pid == 0) {
         /* child -- drop privileges before continuing */
         drop_capabilities(uid);
-        run_profman_dump(profile_fds, reference_profile_fd, code_locations,
-                         code_location_fds, output_fd);
+        run_profman_dump(profile_fds, reference_profile_fd, dex_locations,
+                         apk_fds, output_fd);
         exit(68);   /* only get here on exec failure */
     }
     /* parent */
-    close_all_fds(code_location_fds, "code_location_fds");
+    close_all_fds(apk_fds, "apk_fds");
     close_all_fds(profile_fds, "profile_fds");
     if (close(reference_profile_fd) != 0) {
         PLOG(WARNING) << "Failed to close fd for reference profile";
@@ -1531,12 +1534,7 @@
             run_patchoat(input_fd, out_fd, input_file, out_path, pkgname, instruction_set);
         } else if (dexopt_needed == DEXOPT_DEX2OAT_NEEDED) {
             // Pass dex2oat the relative path to the input file.
-            const char *input_file_name = strrchr(input_file, '/');
-            if (input_file_name == NULL) {
-                input_file_name = input_file;
-            } else {
-                input_file_name++;
-            }
+            const char *input_file_name = get_location_from_path(input_file);
             run_dex2oat(input_fd, out_fd, image_fd, input_file_name, out_path, swap_fd,
                         instruction_set, compiler_filter, vm_safe_mode, debuggable, boot_complete,
                         reference_profile_fd, shared_libraries);
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 6811269..9d130cd 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -162,6 +162,9 @@
     ANativeWindowBuffer* buf;
     int fenceFd = -1;
     int result = c->dequeueBuffer(&buf, &fenceFd);
+    if (result != OK) {
+        return result;
+    }
     sp<Fence> fence(new Fence(fenceFd));
     int waitResult = fence->waitForever("dequeueBuffer_DEPRECATED");
     if (waitResult != OK) {
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 00bfc24..24394a9 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -1794,9 +1794,9 @@
     uint32_t blue_size = 0;
     uint32_t alpha_size = 0;
 
-#define GET_POSITIVE_VALUE(case_name, target) \
+#define GET_NONNEGATIVE_VALUE(case_name, target) \
     case case_name: \
-        if (value > 0) { \
+        if (value >= 0) { \
             target = value; \
         } else { \
             return setError(EGL_BAD_PARAMETER, (EGLClientBuffer)0); \
@@ -1808,12 +1808,12 @@
             GLint attr = *attrib_list++;
             GLint value = *attrib_list++;
             switch (attr) {
-                GET_POSITIVE_VALUE(EGL_WIDTH, width);
-                GET_POSITIVE_VALUE(EGL_HEIGHT, height);
-                GET_POSITIVE_VALUE(EGL_RED_SIZE, red_size);
-                GET_POSITIVE_VALUE(EGL_GREEN_SIZE, green_size);
-                GET_POSITIVE_VALUE(EGL_BLUE_SIZE, blue_size);
-                GET_POSITIVE_VALUE(EGL_ALPHA_SIZE, alpha_size);
+                GET_NONNEGATIVE_VALUE(EGL_WIDTH, width);
+                GET_NONNEGATIVE_VALUE(EGL_HEIGHT, height);
+                GET_NONNEGATIVE_VALUE(EGL_RED_SIZE, red_size);
+                GET_NONNEGATIVE_VALUE(EGL_GREEN_SIZE, green_size);
+                GET_NONNEGATIVE_VALUE(EGL_BLUE_SIZE, blue_size);
+                GET_NONNEGATIVE_VALUE(EGL_ALPHA_SIZE, alpha_size);
                 case EGL_NATIVE_BUFFER_USAGE_ANDROID:
                     if (value & EGL_NATIVE_BUFFER_USAGE_PROTECTED_BIT_ANDROID) {
                         usage |= GRALLOC_USAGE_PROTECTED;
@@ -1836,7 +1836,7 @@
             }
         }
     }
-#undef GET_POSITIVE_VALUE
+#undef GET_NONNEGATIVE_VALUE
 
     // Validate format.
     if (red_size == 8 && green_size == 8 && blue_size == 8) {
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index dffc542..b5d3262 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -1442,6 +1442,8 @@
     // this is used by Layer, which special cases resizes.
     if (flags & eDontUpdateGeometryState)  {
     } else {
+        Layer::State& editCurrentState(getCurrentState());
+        editCurrentState.active = editCurrentState.requested;
         c.active = c.requested;
     }
 
diff --git a/vulkan/libvulkan/swapchain.cpp b/vulkan/libvulkan/swapchain.cpp
index 207c318..adc7d5c 100644
--- a/vulkan/libvulkan/swapchain.cpp
+++ b/vulkan/libvulkan/swapchain.cpp
@@ -200,7 +200,6 @@
 void OrphanSwapchain(VkDevice device, Swapchain* swapchain) {
     if (swapchain->surface.swapchain_handle != HandleFromSwapchain(swapchain))
         return;
-    const auto& dispatch = GetData(device).driver;
     for (uint32_t i = 0; i < swapchain->num_images; i++) {
         if (!swapchain->images[i].dequeued)
             ReleaseSwapchainImage(device, nullptr, -1, swapchain->images[i]);
@@ -253,7 +252,7 @@
     if (!surface)
         return;
     native_window_api_disconnect(surface->window.get(), NATIVE_WINDOW_API_EGL);
-    ALOGE_IF(surface->swapchain_handle != VK_NULL_HANDLE,
+    ALOGV_IF(surface->swapchain_handle != VK_NULL_HANDLE,
              "destroyed VkSurfaceKHR 0x%" PRIx64
              " has active VkSwapchainKHR 0x%" PRIx64,
              reinterpret_cast<uint64_t>(surface_handle),
@@ -410,16 +409,16 @@
     if (!allocator)
         allocator = &GetData(device).allocator;
 
-    ALOGE_IF(create_info->imageArrayLayers != 1,
+    ALOGV_IF(create_info->imageArrayLayers != 1,
              "swapchain imageArrayLayers=%u not supported",
              create_info->imageArrayLayers);
-    ALOGE_IF(create_info->imageColorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
+    ALOGV_IF(create_info->imageColorSpace != VK_COLOR_SPACE_SRGB_NONLINEAR_KHR,
              "swapchain imageColorSpace=%u not supported",
              create_info->imageColorSpace);
-    ALOGE_IF((create_info->preTransform & ~kSupportedTransforms) != 0,
+    ALOGV_IF((create_info->preTransform & ~kSupportedTransforms) != 0,
              "swapchain preTransform=%#x not supported",
              create_info->preTransform);
-    ALOGE_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR ||
+    ALOGV_IF(!(create_info->presentMode == VK_PRESENT_MODE_FIFO_KHR ||
                create_info->presentMode == VK_PRESENT_MODE_MAILBOX_KHR),
              "swapchain presentMode=%u not supported",
              create_info->presentMode);
@@ -427,7 +426,7 @@
     Surface& surface = *SurfaceFromHandle(create_info->surface);
 
     if (surface.swapchain_handle != create_info->oldSwapchain) {
-        ALOGE("Can't create a swapchain for VkSurfaceKHR 0x%" PRIx64
+        ALOGV("Can't create a swapchain for VkSurfaceKHR 0x%" PRIx64
               " because it already has active swapchain 0x%" PRIx64
               " but VkSwapchainCreateInfo::oldSwapchain=0x%" PRIx64,
               reinterpret_cast<uint64_t>(create_info->surface),
@@ -488,7 +487,7 @@
             native_format = HAL_PIXEL_FORMAT_RGB_565;
             break;
         default:
-            ALOGE("unsupported swapchain format %d", create_info->imageFormat);
+            ALOGV("unsupported swapchain format %d", create_info->imageFormat);
             break;
     }
     err = native_window_set_buffers_format(surface.window.get(), native_format);
@@ -720,14 +719,12 @@
                          const VkAllocationCallbacks* allocator) {
     const auto& dispatch = GetData(device).driver;
     Swapchain* swapchain = SwapchainFromHandle(swapchain_handle);
-    ANativeWindow* window =
-        (swapchain->surface.swapchain_handle == swapchain_handle)
-            ? swapchain->surface.window.get()
-            : nullptr;
+    bool active = swapchain->surface.swapchain_handle == swapchain_handle;
+    ANativeWindow* window = active ? swapchain->surface.window.get() : nullptr;
 
     for (uint32_t i = 0; i < swapchain->num_images; i++)
         ReleaseSwapchainImage(device, window, -1, swapchain->images[i]);
-    if (swapchain->surface.swapchain_handle == swapchain_handle)
+    if (active)
         swapchain->surface.swapchain_handle = VK_NULL_HANDLE;
     if (!allocator)
         allocator = &GetData(device).allocator;