Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)

Bug: 166295507
Merged-In: I6d44eff89315b9fb0a032d9127c57e400f730305
Change-Id: I88973ad95767b663396ee6a7e7f586ce6fa9b123
diff --git a/src/connection.c b/src/connection.c
index 7fba999..6152d71 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1251,19 +1251,44 @@
 	return result;
 }
 
-void
-wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
+struct closure_buffer_info {
+	char *buffer;
+	size_t buffer_size;
+	size_t offset;
+};
+
+static void
+asnprintf(struct closure_buffer_info *buffer_info, const char *fmt, ...)
+{
+	va_list args;
+	int written;
+	char *buffer = buffer_info->buffer + buffer_info->offset;
+	size_t size = 0;
+
+	if (buffer_info->buffer_size)
+		size = buffer_info->buffer_size - buffer_info->offset;
+
+	va_start(args, fmt);
+	written = vsnprintf(buffer, size, fmt, args);
+	va_end(args);
+
+	if (buffer_info->buffer_size && (size_t) written > size)
+		written = (int) size;
+
+	if (written > 0)
+		buffer_info->offset += written;
+}
+
+static size_t
+wl_closure_format_to_buffer(struct closure_buffer_info *buffer_info,
+		struct wl_closure *closure, struct wl_object *target, int send,
+		unsigned int time)
 {
 	int i;
 	struct argument_details arg;
 	const char *signature = closure->message->signature;
-	struct timespec tp;
-	unsigned int time;
 
-	clock_gettime(CLOCK_REALTIME, &tp);
-	time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
-
-	fprintf(stderr, "[%10.3f] %s%s@%u.%s(",
+	asnprintf(buffer_info, "[%10.3f] %s%s@%u.%s(",
 		time / 1000.0,
 		send ? " -> " : "",
 		target->interface->name, target->id,
@@ -1272,53 +1297,89 @@
 	for (i = 0; i < closure->count; i++) {
 		signature = get_next_argument(signature, &arg);
 		if (i > 0)
-			fprintf(stderr, ", ");
+			asnprintf(buffer_info, ", ");
 
 		switch (arg.type) {
 		case 'u':
-			fprintf(stderr, "%u", closure->args[i].u);
+			asnprintf(buffer_info, "%u", closure->args[i].u);
 			break;
 		case 'i':
-			fprintf(stderr, "%d", closure->args[i].i);
+			asnprintf(buffer_info, "%d", closure->args[i].i);
 			break;
 		case 'f':
-			fprintf(stderr, "%f",
+			asnprintf(buffer_info, "%f",
 				wl_fixed_to_double(closure->args[i].f));
 			break;
 		case 's':
 			if (closure->args[i].s)
-				fprintf(stderr, "\"%s\"", closure->args[i].s);
+				asnprintf(buffer_info, "\"%s\"", closure->args[i].s);
 			else
-				fprintf(stderr, "nil");
+				asnprintf(buffer_info, "nil");
 			break;
 		case 'o':
 			if (closure->args[i].o)
-				fprintf(stderr, "%s@%u",
-					closure->args[i].o->interface->name,
-					closure->args[i].o->id);
+				asnprintf(buffer_info, "%s@%u",
+						closure->args[i].o->interface->name,
+						closure->args[i].o->id);
 			else
-				fprintf(stderr, "nil");
+				asnprintf(buffer_info, "nil");
 			break;
 		case 'n':
-			fprintf(stderr, "new id %s@",
-				(closure->message->types[i]) ?
-				 closure->message->types[i]->name :
-				  "[unknown]");
+			asnprintf(buffer_info, "new id %s@",
+					(closure->message->types[i]) ?
+					closure->message->types[i]->name :
+					"[unknown]");
 			if (closure->args[i].n != 0)
-				fprintf(stderr, "%u", closure->args[i].n);
+				asnprintf(buffer_info, "%u", closure->args[i].n);
 			else
-				fprintf(stderr, "nil");
+				asnprintf(buffer_info, "nil");
 			break;
 		case 'a':
-			fprintf(stderr, "array");
+			asnprintf(buffer_info, "array");
 			break;
 		case 'h':
-			fprintf(stderr, "fd %d", closure->args[i].h);
+			asnprintf(buffer_info, "fd %d", closure->args[i].h);
 			break;
 		}
 	}
 
-	fprintf(stderr, ")\n");
+	asnprintf(buffer_info, ")\n");
+	return buffer_info->offset;
+}
+
+void
+wl_closure_print(struct wl_closure *closure, struct wl_object *target, int send)
+{
+	struct timespec tp;
+	unsigned int time;
+	char *buffer;
+	size_t buffer_size;
+	struct closure_buffer_info buffer_info;
+
+	clock_gettime(CLOCK_REALTIME, &tp);
+	time = (tp.tv_sec * 1000000L) + (tp.tv_nsec / 1000);
+	// For the first call, pass NULL for the buffer and zero for the size.
+	buffer_info.buffer = NULL;
+	buffer_info.buffer_size = 0;
+	buffer_info.offset = 0;
+	buffer_size = wl_closure_format_to_buffer(&buffer_info, closure, target,
+		send, time);
+	buffer = malloc(buffer_size * sizeof(char));
+	if (buffer == NULL) {
+		wl_log("[%10.3f] %s%s@%u.%s(%s)\n",
+			time / 1000.0,
+			send ? " -> " : "",
+			target->interface->name, target->id,
+			closure->message->name,
+			"Error allocating buffer for the log message");
+		return;
+	}
+	buffer_info.buffer = buffer;
+	buffer_info.buffer_size = buffer_size;
+	buffer_info.offset = 0;
+	wl_closure_format_to_buffer(&buffer_info, closure, target, send, time);
+	wl_log("%s", buffer);
+	free(buffer);
 }
 
 static int
diff --git a/src/wayland-client-core.h b/src/wayland-client-core.h
index 03e781b..84c83bf 100644
--- a/src/wayland-client-core.h
+++ b/src/wayland-client-core.h
@@ -260,6 +260,9 @@
 void
 wl_log_set_handler_client(wl_log_func_t handler);
 
+void
+wl_set_debug_client_flag(int value);
+
 #ifdef  __cplusplus
 }
 #endif
diff --git a/src/wayland-client.c b/src/wayland-client.c
index b0805f1..4b9bd39 100644
--- a/src/wayland-client.c
+++ b/src/wayland-client.c
@@ -2194,3 +2194,9 @@
 {
 	wl_log_handler = handler;
 }
+
+WL_EXPORT void
+wl_set_debug_client_flag(int value)
+{
+	debug_client = value;
+}