resolve merge conflicts of 69ed5d9 to stage-aosp-master am: d269bf4328
am: c1965c958c
Change-Id: I8b58348b884eedac1852984c65f87f014256b4d0
diff --git a/include/hardware/audio.h b/include/hardware/audio.h
index 36bfa86..ec7fd4b 100644
--- a/include/hardware/audio.h
+++ b/include/hardware/audio.h
@@ -253,7 +253,8 @@
/* type of asynchronous write callback events. Mutually exclusive */
typedef enum {
STREAM_CBK_EVENT_WRITE_READY, /* non blocking write completed */
- STREAM_CBK_EVENT_DRAIN_READY /* drain completed */
+ STREAM_CBK_EVENT_DRAIN_READY, /* drain completed */
+ STREAM_CBK_EVENT_ERROR, /* stream hit some error, let AF take action */
} stream_callback_event_t;
typedef int (*stream_callback_t)(stream_callback_event_t event, void *param, void *cookie);
diff --git a/include/hardware/bt_hf.h b/include/hardware/bt_hf.h
index 7dcb40a..0a77675 100644
--- a/include/hardware/bt_hf.h
+++ b/include/hardware/bt_hf.h
@@ -74,6 +74,20 @@
BTHF_CHLD_TYPE_ADDHELDTOCONF, // Add all held calls to a conference
} bthf_chld_type_t;
+
+/* HF Indicators HFP 1.7 */
+typedef enum
+{
+ BTHF_HF_IND_ENHANCED_DRIVER_SAFETY = 1,
+ BTHF_HF_IND_BATTERY_LEVEL_STATUS = 2,
+} bthf_hf_ind_type_t;
+
+typedef enum
+{
+ BTHF_HF_IND_DISABLED = 0,
+ BTHF_HF_IND_ENABLED,
+} bthf_hf_ind_status_t;
+
/** Callback for connection state change.
* state will have one of the values from BtHfConnectionState
*/
@@ -152,6 +166,15 @@
*/
typedef void (* bthf_key_pressed_cmd_callback)(bt_bdaddr_t *bd_addr);
+/** Callback for BIND. Pass the remote HF Indicators supported.
+ */
+typedef void (* bthf_bind_cmd_callback)(char *at_string, bt_bdaddr_t *bd_addr);
+
+/** Callback for BIEV. Pass the change in the Remote HF indicator values
+ */
+typedef void (* bthf_biev_cmd_callback)(bthf_hf_ind_type_t ind_id, int ind_value,
+ bt_bdaddr_t *bd_addr);
+
/** BT-HF callback structure. */
typedef struct {
/** set to sizeof(BtHfCallbacks) */
@@ -172,6 +195,8 @@
bthf_cops_cmd_callback cops_cmd_cb;
bthf_clcc_cmd_callback clcc_cmd_cb;
bthf_unknown_at_cmd_callback unknown_at_cmd_cb;
+ bthf_bind_cmd_callback bind_cb;
+ bthf_biev_cmd_callback biev_cb;
bthf_key_pressed_cmd_callback key_pressed_cmd_cb;
} bthf_callbacks_t;
@@ -294,6 +319,10 @@
/** configureation for the SCO codec */
bt_status_t (*configure_wbs)( bt_bdaddr_t *bd_addr ,bthf_wbs_config_t config );
+
+ /** Response for HF Indicator change (+BIND) */
+ bt_status_t (*bind_response)(bthf_hf_ind_type_t ind_id, bthf_hf_ind_status_t ind_status,
+ bt_bdaddr_t *bd_addr);
} bthf_interface_t;
__END_DECLS
diff --git a/include/hardware/context_hub.h b/include/hardware/context_hub.h
index 99756cb..828f2dd 100644
--- a/include/hardware/context_hub.h
+++ b/include/hardware/context_hub.h
@@ -358,6 +358,27 @@
*/
/**
+ * CONTEXT_HUB_OS_REBOOT
+ * Reboots context hub OS, restarts all the nanoApps.
+ * No reboot notification is sent to nanoApps; reboot happens immediately and
+ * unconditionally; all volatile FW state and any data is lost as a result
+ *
+ * Payload : none
+ *
+ * Response : status_response_t
+ * On receipt of a successful response, it is
+ * expected that
+ *
+ * i) system reboot has completed;
+ * status contains reboot reason code (platform-specific)
+ *
+ * Unsolicited response:
+ * System may send unsolicited response at any time;
+ * this should be interpreted as FW reboot, and necessary setup
+ * has to be done (same or similar to the setup done on system boot)
+ */
+
+/**
* All communication between the context hubs and the Context Hub Service is in
* the form of messages. Some message types are distinguished and their
* Semantics shall be well defined.
@@ -372,6 +393,7 @@
CONTEXT_HUB_UNLOAD_APP = 4, // Unload a specified app
CONTEXT_HUB_QUERY_APPS = 5, // Query for app(s) info on hub
CONTEXT_HUB_QUERY_MEMORY = 6, // Query for memory info
+ CONTEXT_HUB_OS_REBOOT = 7, // Request to reboot context HUB OS
} hub_messages_e;
#define CONTEXT_HUB_TYPE_PRIVATE_MSG_BASE 0x00400
diff --git a/include/hardware/gralloc.h b/include/hardware/gralloc.h
index ef86f90..779915c 100644
--- a/include/hardware/gralloc.h
+++ b/include/hardware/gralloc.h
@@ -379,6 +379,38 @@
return device->common.close(&device->common);
}
+/**
+ * map_usage_to_memtrack should be called after allocating a gralloc buffer.
+ *
+ * @param usage - it is the flag used when alloc function is called.
+ *
+ * This function maps the gralloc usage flags to appropriate memtrack bucket.
+ * GrallocHAL implementers and users should make an additional ION_IOCTL_TAG
+ * call using the memtrack tag returned by this function. This will help the
+ * in-kernel memtack to categorize the memory allocated by different processes
+ * according to their usage.
+ *
+ */
+static inline const char* map_usage_to_memtrack(uint32_t usage) {
+ usage &= GRALLOC_USAGE_ALLOC_MASK;
+
+ if ((usage & GRALLOC_USAGE_HW_CAMERA_WRITE) != 0) {
+ return "camera";
+ } else if ((usage & GRALLOC_USAGE_HW_VIDEO_ENCODER) != 0 ||
+ (usage & GRALLOC_USAGE_EXTERNAL_DISP) != 0) {
+ return "video";
+ } else if ((usage & GRALLOC_USAGE_HW_RENDER) != 0 ||
+ (usage & GRALLOC_USAGE_HW_TEXTURE) != 0) {
+ return "gl";
+ } else if ((usage & GRALLOC_USAGE_HW_CAMERA_READ) != 0) {
+ return "camera";
+ } else if ((usage & GRALLOC_USAGE_SW_READ_MASK) != 0 ||
+ (usage & GRALLOC_USAGE_SW_WRITE_MASK) != 0) {
+ return "cpu";
+ }
+ return "graphics";
+}
+
__END_DECLS
#endif // ANDROID_GRALLOC_INTERFACE_H
diff --git a/include/hardware/gralloc1.h b/include/hardware/gralloc1.h
new file mode 100644
index 0000000..58c0e33
--- /dev/null
+++ b/include/hardware/gralloc1.h
@@ -0,0 +1,887 @@
+/*
+ * Copyright 2015 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 ANDROID_HARDWARE_GRALLOC1_H
+#define ANDROID_HARDWARE_GRALLOC1_H
+
+#include <hardware/hardware.h>
+#include <system/window.h>
+
+__BEGIN_DECLS
+
+#define GRALLOC_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0)
+#define GRALLOC_HARDWARE_MODULE_ID "gralloc"
+
+/*
+ * Enums
+ */
+
+typedef enum {
+ GRALLOC1_CAPABILITY_INVALID = 0,
+
+ /* If this capability is supported, then the outBuffers parameter to
+ * allocate may be NULL, which instructs the device to report whether the
+ * given allocation is possible or not. */
+ GRALLOC1_CAPABILITY_TEST_ALLOCATE = 1,
+ GRALLOC1_LAST_CAPABILITY = 1,
+} gralloc1_capability_t;
+
+typedef enum {
+ GRALLOC1_CONSUMER_USAGE_NONE = 0,
+ GRALLOC1_CONSUMER_USAGE_CPU_READ_NEVER = 0,
+ /* 1ULL << 0 */
+ GRALLOC1_CONSUMER_USAGE_CPU_READ = 1ULL << 1,
+ GRALLOC1_CONSUMER_USAGE_CPU_READ_OFTEN = 1ULL << 2 |
+ GRALLOC1_CONSUMER_USAGE_CPU_READ,
+ /* 1ULL << 3 */
+ /* 1ULL << 4 */
+ /* 1ULL << 5 */
+ /* 1ULL << 6 */
+ /* 1ULL << 7 */
+ GRALLOC1_CONSUMER_USAGE_GPU_TEXTURE = 1ULL << 8,
+ /* 1ULL << 9 */
+ /* 1ULL << 10 */
+ GRALLOC1_CONSUMER_USAGE_HWCOMPOSER = 1ULL << 11,
+ GRALLOC1_CONSUMER_USAGE_CLIENT_TARGET = 1ULL << 12,
+ /* 1ULL << 13 */
+ /* 1ULL << 14 */
+ GRALLOC1_CONSUMER_USAGE_CURSOR = 1ULL << 15,
+ GRALLOC1_CONSUMER_USAGE_VIDEO_ENCODER = 1ULL << 16,
+ /* 1ULL << 17 */
+ GRALLOC1_CONSUMER_USAGE_CAMERA = 1ULL << 18,
+ /* 1ULL << 19 */
+ GRALLOC1_CONSUMER_USAGE_RENDERSCRIPT = 1ULL << 20,
+
+ /* Indicates that the consumer may attach buffers to their end of the
+ * BufferQueue, which means that the producer may never have seen a given
+ * dequeued buffer before. May be ignored by the gralloc device. */
+ GRALLOC1_CONSUMER_USAGE_FOREIGN_BUFFERS = 1ULL << 21,
+
+ /* 1ULL << 22 */
+ /* 1ULL << 23 */
+ /* 1ULL << 24 */
+ /* 1ULL << 25 */
+ /* 1ULL << 26 */
+ /* 1ULL << 27 */
+
+ /* Bits reserved for implementation-specific usage flags */
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_0 = 1ULL << 28,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_1 = 1ULL << 29,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_2 = 1ULL << 30,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_3 = 1ULL << 31,
+
+ /* 1ULL << 32 */
+ /* 1ULL << 33 */
+ /* 1ULL << 34 */
+ /* 1ULL << 35 */
+ /* 1ULL << 36 */
+ /* 1ULL << 37 */
+ /* 1ULL << 38 */
+ /* 1ULL << 39 */
+ /* 1ULL << 40 */
+ /* 1ULL << 41 */
+ /* 1ULL << 42 */
+ /* 1ULL << 43 */
+ /* 1ULL << 44 */
+ /* 1ULL << 45 */
+ /* 1ULL << 46 */
+ /* 1ULL << 47 */
+
+ /* Bits reserved for implementation-specific usage flags */
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_19 = 1ULL << 48,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_18 = 1ULL << 49,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_17 = 1ULL << 50,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_16 = 1ULL << 51,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_15 = 1ULL << 52,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_14 = 1ULL << 53,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_13 = 1ULL << 54,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_12 = 1ULL << 55,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_11 = 1ULL << 56,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_10 = 1ULL << 57,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_9 = 1ULL << 58,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_8 = 1ULL << 59,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_7 = 1ULL << 60,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_6 = 1ULL << 61,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_5 = 1ULL << 62,
+ GRALLOC1_CONSUMER_USAGE_PRIVATE_4 = 1ULL << 63,
+} gralloc1_consumer_usage_t;
+
+typedef enum {
+ GRALLOC1_FUNCTION_INVALID = 0,
+ GRALLOC1_FUNCTION_DUMP = 1,
+ GRALLOC1_FUNCTION_CREATE_DESCRIPTOR = 2,
+ GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR = 3,
+ GRALLOC1_FUNCTION_SET_CONSUMER_USAGE = 4,
+ GRALLOC1_FUNCTION_SET_DIMENSIONS = 5,
+ GRALLOC1_FUNCTION_SET_FORMAT = 6,
+ GRALLOC1_FUNCTION_SET_PRODUCER_USAGE = 7,
+ GRALLOC1_FUNCTION_GET_BACKING_STORE = 8,
+ GRALLOC1_FUNCTION_GET_CONSUMER_USAGE = 9,
+ GRALLOC1_FUNCTION_GET_DIMENSIONS = 10,
+ GRALLOC1_FUNCTION_GET_FORMAT = 11,
+ GRALLOC1_FUNCTION_GET_PRODUCER_USAGE = 12,
+ GRALLOC1_FUNCTION_GET_STRIDE = 13,
+ GRALLOC1_FUNCTION_ALLOCATE = 14,
+ GRALLOC1_FUNCTION_RETAIN = 15,
+ GRALLOC1_FUNCTION_RELEASE = 16,
+ GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES = 17,
+ GRALLOC1_FUNCTION_LOCK = 18,
+ GRALLOC1_FUNCTION_LOCK_FLEX = 19,
+ GRALLOC1_FUNCTION_UNLOCK = 20,
+ GRALLOC1_LAST_FUNCTION = 20,
+} gralloc1_function_descriptor_t;
+
+typedef enum {
+ GRALLOC1_ERROR_NONE = 0,
+ GRALLOC1_ERROR_BAD_DESCRIPTOR = 1,
+ GRALLOC1_ERROR_BAD_HANDLE = 2,
+ GRALLOC1_ERROR_BAD_VALUE = 3,
+ GRALLOC1_ERROR_NOT_SHARED = 4,
+ GRALLOC1_ERROR_NO_RESOURCES = 5,
+ GRALLOC1_ERROR_UNDEFINED = 6,
+ GRALLOC1_ERROR_UNSUPPORTED = 7,
+} gralloc1_error_t;
+
+typedef enum {
+ GRALLOC1_PRODUCER_USAGE_NONE = 0,
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE_NEVER = 0,
+ /* 1ULL << 0 */
+ GRALLOC1_PRODUCER_USAGE_CPU_READ = 1ULL << 1,
+ GRALLOC1_PRODUCER_USAGE_CPU_READ_OFTEN = 1ULL << 2 |
+ GRALLOC1_PRODUCER_USAGE_CPU_READ,
+ /* 1ULL << 3 */
+ /* 1ULL << 4 */
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE = 1ULL << 5,
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE_OFTEN = 1ULL << 6 |
+ GRALLOC1_PRODUCER_USAGE_CPU_WRITE,
+ /* 1ULL << 7 */
+ /* 1ULL << 8 */
+ GRALLOC1_PRODUCER_USAGE_GPU_RENDER_TARGET = 1ULL << 9,
+ /* 1ULL << 10 */
+ /* 1ULL << 11 */
+ /* 1ULL << 12 */
+ /* 1ULL << 13 */
+
+ /* The consumer must have a hardware-protected path to an external display
+ * sink for this buffer. If a hardware-protected path is not available, then
+ * do not attempt to display this buffer. */
+ GRALLOC1_PRODUCER_USAGE_PROTECTED = 1ULL << 14,
+
+ /* 1ULL << 15 */
+ /* 1ULL << 16 */
+ GRALLOC1_PRODUCER_USAGE_CAMERA = 1ULL << 17,
+ /* 1ULL << 18 */
+ /* 1ULL << 19 */
+ /* 1ULL << 20 */
+ /* 1ULL << 21 */
+ GRALLOC1_PRODUCER_USAGE_VIDEO_DECODER = 1ULL << 22,
+ /* 1ULL << 23 */
+ /* 1ULL << 24 */
+ /* 1ULL << 25 */
+ /* 1ULL << 26 */
+ /* 1ULL << 27 */
+
+ /* Bits reserved for implementation-specific usage flags */
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_0 = 1ULL << 28,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_1 = 1ULL << 29,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_2 = 1ULL << 30,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_3 = 1ULL << 31,
+
+ /* 1ULL << 32 */
+ /* 1ULL << 33 */
+ /* 1ULL << 34 */
+ /* 1ULL << 35 */
+ /* 1ULL << 36 */
+ /* 1ULL << 37 */
+ /* 1ULL << 38 */
+ /* 1ULL << 39 */
+ /* 1ULL << 40 */
+ /* 1ULL << 41 */
+ /* 1ULL << 42 */
+ /* 1ULL << 43 */
+ /* 1ULL << 44 */
+ /* 1ULL << 45 */
+ /* 1ULL << 46 */
+ /* 1ULL << 47 */
+
+ /* Bits reserved for implementation-specific usage flags */
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_19 = 1ULL << 48,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_18 = 1ULL << 49,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_17 = 1ULL << 50,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_16 = 1ULL << 51,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_15 = 1ULL << 52,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_14 = 1ULL << 53,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_13 = 1ULL << 54,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_12 = 1ULL << 55,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_11 = 1ULL << 56,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_10 = 1ULL << 57,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_9 = 1ULL << 58,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_8 = 1ULL << 59,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_7 = 1ULL << 60,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_6 = 1ULL << 61,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_5 = 1ULL << 62,
+ GRALLOC1_PRODUCER_USAGE_PRIVATE_4 = 1ULL << 63,
+} gralloc1_producer_usage_t;
+
+/*
+ * Typedefs
+ */
+
+typedef void (*gralloc1_function_pointer_t)();
+
+typedef uint64_t gralloc1_backing_store_t;
+typedef uint64_t gralloc1_buffer_descriptor_t;
+
+/*
+ * Device Struct
+ */
+
+typedef struct gralloc1_device {
+ /* Must be the first member of this struct, since a pointer to this struct
+ * will be generated by casting from a hw_device_t* */
+ struct hw_device_t common;
+
+ /* getCapabilities(..., outCount, outCapabilities)
+ *
+ * Provides a list of capabilities (described in the definition of
+ * gralloc1_capability_t above) supported by this device. This list must not
+ * change after the device has been loaded.
+ *
+ * Parameters:
+ * outCount - if outCapabilities was NULL, the number of capabilities
+ * which would have been returned; if outCapabilities was not NULL,
+ * the number of capabilities returned, which must not exceed the
+ * value stored in outCount prior to the call
+ * outCapabilities - a list of capabilities supported by this device; may
+ * be NULL, in which case this function must write into outCount the
+ * number of capabilities which would have been written into
+ * outCapabilities
+ */
+ void (*getCapabilities)(struct gralloc1_device* device, uint32_t* outCount,
+ int32_t* /*gralloc1_capability_t*/ outCapabilities);
+
+ /* getFunction(..., descriptor)
+ *
+ * Returns a function pointer which implements the requested description.
+ *
+ * Parameters:
+ * descriptor - the function to return
+ *
+ * Returns either a function pointer implementing the requested descriptor
+ * or NULL if the described function is not supported by this device.
+ */
+ gralloc1_function_pointer_t (*getFunction)(struct gralloc1_device* device,
+ int32_t /*gralloc1_function_descriptor_t*/ descriptor);
+} gralloc1_device_t;
+
+static inline int gralloc1_open(const struct hw_module_t* module,
+ gralloc1_device_t** device) {
+ return module->methods->open(module, GRALLOC_HARDWARE_MODULE_ID,
+ (struct hw_device_t**) device);
+}
+
+static inline int gralloc1_close(gralloc1_device_t* device) {
+ return device->common.close(&device->common);
+}
+
+/* dump(..., outSize, outBuffer)
+ * Function descriptor: GRALLOC1_FUNCTION_DUMP
+ * Must be provided by all gralloc1 devices
+ *
+ * Retrieves implementation-defined debug information, which will be displayed
+ * during, for example, `dumpsys SurfaceFlinger`.
+ *
+ * If called with outBuffer == NULL, the device should store a copy of the
+ * desired output and return its length in bytes in outSize. If the device
+ * already has a stored copy, that copy should be purged and replaced with a
+ * fresh copy.
+ *
+ * If called with outBuffer != NULL, the device should copy its stored version
+ * of the output into outBuffer and store how many bytes of data it copied into
+ * outSize. Prior to this call, the client will have populated outSize with the
+ * maximum number of bytes outBuffer can hold. The device must not write more
+ * than this amount into outBuffer. If the device does not currently have a
+ * stored copy, then it should return 0 in outSize.
+ *
+ * Any data written into outBuffer need not be null-terminated.
+ *
+ * Parameters:
+ * outSize - if outBuffer was NULL, the number of bytes needed to copy the
+ * device's stored output; if outBuffer was not NULL, the number of bytes
+ * written into it, which must not exceed the value stored in outSize
+ * prior to the call; pointer will be non-NULL
+ * outBuffer - the buffer to write the dump output into; may be NULL as
+ * described above; data written into this buffer need not be
+ * null-terminated
+ */
+typedef void (*GRALLOC1_PFN_DUMP)(gralloc1_device_t* device, uint32_t* outSize,
+ char* outBuffer);
+
+/*
+ * Buffer descriptor lifecycle functions
+ *
+ * All of these functions take as their first parameter a device pointer, so
+ * this parameter is omitted from the described parameter lists.
+ */
+
+/* createDescriptor(..., outDescriptor)
+ * Function descriptor: GRALLOC1_FUNCTION_CREATE_DESCRIPTOR
+ * Must be provided by all gralloc1 devices
+ *
+ * Creates a new, empty buffer descriptor.
+ *
+ * Parameters:
+ * outDescriptor - the new buffer descriptor
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_NO_RESOURCES - no more descriptors can currently be created
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_CREATE_DESCRIPTOR)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t* outDescriptor);
+
+/* destroyDescriptor(..., descriptor)
+ * Function descriptor: GRALLOC1_FUNCTION_DESTROY_DESCRIPTOR
+ * Must be provided by all gralloc1 devices
+ *
+ * Destroys an existing buffer descriptor.
+ *
+ * Parameters:
+ * descriptor - the buffer descriptor to destroy
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - descriptor does not refer to a valid
+ * buffer descriptor
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_DESTROY_DESCRIPTOR)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor);
+
+/*
+ * Buffer descriptor modification functions
+ *
+ * All of these functions take as their first two parameters a device pointer
+ * and a buffer descriptor, so these parameters are omitted from the described
+ * parameter lists.
+ */
+
+/* setConsumerUsage(..., usage)
+ * Function descriptor: GRALLOC1_FUNCTION_SET_CONSUMER_USAGE
+ * Must be provided by all gralloc1 devices
+ *
+ * Sets the desired consumer usage flags of the buffer.
+ *
+ * Valid usage flags can be found in the definition of gralloc1_consumer_usage_t
+ * above.
+ *
+ * Parameters:
+ * usage - the desired consumer usage flags
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - the buffer descriptor is invalid
+ * GRALLOC1_ERROR_BAD_VALUE - an invalid usage flag was passed in
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_CONSUMER_USAGE)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+ uint64_t /*gralloc1_consumer_usage_t*/ usage);
+
+/* setDimensions(..., width, height)
+ * Function descriptor: GRALLOC1_FUNCTION_SET_DIMENSIONS
+ * Must be provided by all gralloc1 devices
+ *
+ * Sets the desired width and height of the buffer in pixels.
+ *
+ * The width specifies how many columns of pixels should be in the allocated
+ * buffer, but does not necessarily represent the offset in columns between the
+ * same column in adjacent rows. If this offset is required, consult getStride
+ * below.
+ *
+ * The height specifies how many rows of pixels should be in the allocated
+ * buffer.
+ *
+ * Parameters:
+ * width - the desired width in pixels
+ * height - the desired height in pixels
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - the buffer descriptor is invalid
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_DIMENSIONS)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+ uint32_t width, uint32_t height);
+
+/* setFormat(..., format)
+ * Function descriptor: GRALLOC1_FUNCTION_SET_FORMAT
+ * Must be provided by all gralloc1 devices
+ *
+ * Sets the desired format of the buffer.
+ *
+ * The valid formats can be found in <system/graphics.h>.
+ *
+ * Parameters:
+ * format - the desired format
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - the buffer descriptor is invalid
+ * GRALLOC1_ERROR_BAD_VALUE - format is invalid
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_FORMAT)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+ int32_t /*android_pixel_format_t*/ format);
+
+/* setProducerUsage(..., usage)
+ * Function descriptor: GRALLOC1_FUNCTION_SET_PRODUCER_USAGE
+ * Must be provided by all gralloc1 devices
+ *
+ * Sets the desired producer usage flags of the buffer.
+ *
+ * Valid usage flags can be found in the definition of gralloc1_producer_usage_t
+ * above.
+ *
+ * Parameters:
+ * usage - the desired producer usage flags
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - the buffer descriptor is invalid
+ * GRALLOC1_ERROR_BAD_VALUE - an invalid usage flag was passed in
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_SET_PRODUCER_USAGE)(
+ gralloc1_device_t* device, gralloc1_buffer_descriptor_t descriptor,
+ uint64_t /*gralloc1_producer_usage_t*/ usage);
+
+/*
+ * Buffer handle query functions
+ *
+ * All of these functions take as their first two parameters a device pointer
+ * and a buffer handle, so these parameters are omitted from the described
+ * parameter lists.
+ *
+ * [1] Currently many of these functions may return GRALLOC1_ERROR_UNSUPPORTED,
+ * which means that the device is not able to retrieve the requested information
+ * from the buffer. This is necessary to enable a smooth transition from earlier
+ * versions of the gralloc HAL, but gralloc1 implementers are strongly
+ * discouraged from returning this value, as future versions of the platform
+ * code will require all of these functions to succeed given a valid handle.
+ */
+
+/* getBackingStore(..., outStore)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_BACKING_STORE
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets a value that uniquely identifies the backing store of the given buffer.
+ *
+ * Buffers which share a backing store should return the same value from this
+ * function. If the buffer is present in more than one process, the backing
+ * store value for that buffer is not required to be the same in every process.
+ *
+ * Parameters:
+ * outStore - the backing store identifier for this buffer
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the
+ * backing store identifier from the buffer; see note [1] in this
+ * section's header for more information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_BACKING_STORE)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ gralloc1_backing_store_t* outStore);
+
+/* getConsumerUsage(..., outUsage)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_CONSUMER_USAGE
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets the consumer usage flags which were used to allocate this buffer.
+ *
+ * Usage flags can be found in the definition of gralloc1_consumer_usage_t above
+ *
+ * Parameters:
+ * outUsage - the consumer usage flags used to allocate this buffer; must be
+ * non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the
+ * dimensions from the buffer; see note [1] in this section's header for
+ * more information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_CONSUMER_USAGE)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ uint64_t* /*gralloc1_consumer_usage_t*/ outUsage);
+
+/* getDimensions(..., outWidth, outHeight)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_DIMENSIONS
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets the width and height of the buffer in pixels.
+ *
+ * See setDimensions for more information about these values.
+ *
+ * Parameters:
+ * outWidth - the width of the buffer in pixels, must be non-NULL
+ * outHeight - the height of the buffer in pixels, must be non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the
+ * dimensions from the buffer; see note [1] in this section's header for
+ * more information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_DIMENSIONS)(
+ gralloc1_device_t* device, buffer_handle_t buffer, uint32_t* outWidth,
+ uint32_t* outHeight);
+
+/* getFormat(..., outFormat)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_FORMAT
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets the format of the buffer.
+ *
+ * The valid formats can be found in the HAL_PIXEL_FORMAT_* enum in
+ * system/graphics.h.
+ *
+ * Parameters:
+ * outFormat - the format of the buffer; must be non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the format
+ * from the buffer; see note [1] in this section's header for more
+ * information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_FORMAT)(
+ gralloc1_device_t* device, buffer_handle_t descriptor,
+ int32_t* outFormat);
+
+/* getProducerUsage(..., outUsage)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_PRODUCER_USAGE
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets the producer usage flags which were used to allocate this buffer.
+ *
+ * Usage flags can be found in the definition of gralloc1_producer_usage_t above
+ *
+ * Parameters:
+ * outUsage - the producer usage flags used to allocate this buffer; must be
+ * non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the usage
+ * from the buffer; see note [1] in this section's header for more
+ * information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_PRODUCER_USAGE)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ uint64_t* /*gralloc1_producer_usage_t*/ outUsage);
+
+/* getStride(..., outStride)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_STRIDE
+ * Must be provided by all gralloc1 devices
+ *
+ * Gets the stride of the buffer in pixels.
+ *
+ * The stride is the offset in pixel-sized elements between the same column in
+ * two adjacent rows of pixels. This may not be equal to the width of the
+ * buffer.
+ *
+ * Parameters:
+ * outStride - the stride in pixels; must be non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNDEFINED - the notion of a stride is not meaningful for
+ * this format
+ * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to retrieve the stride
+ * from the descriptor; see note [1] in this section's header for more
+ * information
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_STRIDE)(
+ gralloc1_device_t* device, buffer_handle_t buffer, uint32_t* outStride);
+
+/*
+ * Buffer management functions
+ */
+
+/* allocate(..., numDescriptors, descriptors, outBuffers)
+ * Function descriptor: GRALLOC1_FUNCTION_ALLOCATE
+ * Must be provided by all gralloc1 devices
+ *
+ * Attempts to allocate a number of buffers sharing a backing store.
+ *
+ * Each buffer will correspond to one of the descriptors passed into the
+ * function. If the device is unable to share the backing store between the
+ * buffers, it should attempt to allocate the buffers with different backing
+ * stores and return GRALLOC1_ERROR_NOT_SHARED if it is successful.
+ *
+ * If this call is successful, the client is responsible for freeing the
+ * buffer_handle_t using release() when it is finished with the buffer. It is
+ * not necessary to call retain() on the returned buffers, as they must have a
+ * reference added by the device before returning.
+ *
+ * If GRALLOC1_CAPABILITY_TEST_ALLOCATE is supported by this device, outBuffers
+ * may be NULL. In this case, the device must not attempt to allocate any
+ * buffers, but instead must return either GRALLOC1_ERROR_NONE if such an
+ * allocation is possible (ignoring potential resource contention which might
+ * lead to a GRALLOC1_ERROR_NO_RESOURCES error), GRALLOC1_ERROR_NOT_SHARED if
+ * the buffers can be allocated, but cannot share a backing store, or
+ * GRALLOC1_ERROR_UNSUPPORTED if one or more of the descriptors can never be
+ * allocated by the device.
+ *
+ * Parameters:
+ * numDescriptors - the number of buffer descriptors, which must also be equal
+ * to the size of the outBuffers array
+ * descriptors - the buffer descriptors to attempt to allocate
+ * outBuffers - the allocated buffers; must be non-NULL unless the device
+ * supports GRALLOC1_CAPABILITY_TEST_ALLOCATE (see above), and must not be
+ * modified by the device if allocation is unsuccessful
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_DESCRIPTOR - one of the descriptors does not refer to a
+ * valid buffer descriptor
+ * GRALLOC1_ERROR_NOT_SHARED - allocation was successful, but required more
+ * than one backing store to satisfy all of the buffer descriptors
+ * GRALLOC1_ERROR_NO_RESOURCES - allocation failed because one or more of the
+ * backing stores could not be created at this time (but this allocation
+ * might succeed at a future time)
+ * GRALLOC1_ERROR_UNSUPPORTED - one or more of the descriptors can never be
+ * satisfied by the device
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_ALLOCATE)(
+ gralloc1_device_t* device, uint32_t numDescriptors,
+ const gralloc1_buffer_descriptor_t* descriptors,
+ buffer_handle_t* outBuffers);
+
+/* retain(..., buffer)
+ * Function descriptor: GRALLOC1_FUNCTION_RETAIN
+ * Must be provided by all gralloc1 devices
+ *
+ * Adds a reference to the given buffer.
+ *
+ * This function must be called when a buffer_handle_t is received from a remote
+ * process to prevent the buffer's data from being freed when the remote process
+ * releases the buffer. It may also be called to increase the reference count if
+ * two components in the same process want to interact with the buffer
+ * independently.
+ *
+ * Parameters:
+ * buffer - the buffer to which a reference should be added
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_NO_RESOURCES - it is not possible to add a reference to this
+ * buffer at this time
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_RETAIN)(
+ gralloc1_device_t* device, buffer_handle_t buffer);
+
+/* release(..., buffer)
+ * Function descriptor: GRALLOC1_FUNCTION_RELEASE
+ * Must be provided by all gralloc1 devices
+ *
+ * Removes a reference from the given buffer.
+ *
+ * If no references remain, the buffer should be freed. When the last buffer
+ * referring to a particular backing store is freed, that backing store should
+ * also be freed.
+ *
+ * Parameters:
+ * buffer - the buffer from which a reference should be removed
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_RELEASE)(
+ gralloc1_device_t* device, buffer_handle_t buffer);
+
+/*
+ * Buffer access functions
+ *
+ * All of these functions take as their first parameter a device pointer, so
+ * this parameter is omitted from the described parameter lists.
+ */
+
+typedef struct gralloc1_rect {
+ int32_t left;
+ int32_t top;
+ int32_t width;
+ int32_t height;
+} gralloc1_rect_t;
+
+/* getNumFlexPlanes(..., buffer, outNumPlanes)
+ * Function descriptor: GRALLOC1_FUNCTION_GET_NUM_FLEX_PLANES
+ * Must be provided by all gralloc1 devices
+ *
+ * Returns the number of flex layout planes which are needed to represent the
+ * given buffer. This may be used to efficiently allocate only as many plane
+ * structures as necessary before calling into lockFlex.
+ *
+ * If the given buffer cannot be locked as a flex format, this function may
+ * return GRALLOC1_ERROR_UNSUPPORTED (as lockFlex would).
+ *
+ * Parameters:
+ * buffer - the buffers for which the number of planes should be queried
+ * outNumPlanes - the number of flex planes required to describe the given
+ * buffer; must be non-NULL
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_UNSUPPORTED - the buffer's format cannot be represented in a
+ * flex layout
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_NUM_FLEX_PLANES)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ uint32_t* outNumPlanes);
+
+/* lock(..., buffer, producerUsage, consumerUsage, accessRegion, outData,
+ * acquireFence)
+ * Function descriptor: GRALLOC1_FUNCTION_LOCK
+ * Must be provided by all gralloc1 devices
+ *
+ * Locks the given buffer for the specified CPU usage.
+ *
+ * Exactly one of producerUsage and consumerUsage must be *_USAGE_NONE. The
+ * usage which is not *_USAGE_NONE must be one of the *_USAGE_CPU_* values, as
+ * applicable. Locking a buffer for a non-CPU usage is not supported.
+ *
+ * Locking the same buffer simultaneously from multiple threads is permitted,
+ * but if any of the threads attempt to lock the buffer for writing, the
+ * behavior is undefined, except that it must not cause process termination or
+ * block the client indefinitely. Leaving the buffer content in an indeterminate
+ * state or returning an error are both acceptable.
+ *
+ * The client must not modify the content of the buffer outside of accessRegion,
+ * and the device need not guarantee that content outside of accessRegion is
+ * valid for reading. The result of reading or writing outside of accessRegion
+ * is undefined, except that it must not cause process termination.
+ *
+ * outData must be a non-NULL pointer, the contents of which which will be
+ * filled with a pointer to the locked buffer memory. This address will
+ * represent the top-left corner of the entire buffer, even if accessRegion does
+ * not begin at the top-left corner.
+ *
+ * acquireFence is a file descriptor referring to a acquire sync fence object,
+ * which will be signaled when it is safe for the device to access the contents
+ * of the buffer (prior to locking). If it is already safe to access the buffer
+ * contents, -1 may be passed instead.
+ *
+ * Parameters:
+ * buffer - the buffer to lock
+ * producerUsage - the producer usage flags to request; either this or
+ * consumerUsage must be GRALLOC1_*_USAGE_NONE, and the other must be a
+ * CPU usage
+ * consumerUsage - the consumer usage flags to request; either this or
+ * producerUsage must be GRALLOC1_*_USAGE_NONE, and the other must be a
+ * CPU usage
+ * accessRegion - the portion of the buffer that the client intends to access;
+ * must be non-NULL
+ * outData - will be filled with a CPU-accessible pointer to the buffer data;
+ * must be non-NULL
+ * acquireFence - a sync fence file descriptor as described above
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_BAD_VALUE - neither or both of producerUsage and
+ * consumerUsage were GRALLOC1_*_USAGE_NONE, or the usage which was not
+ * *_USAGE_NONE was not a CPU usage
+ * GRALLOC1_ERROR_NO_RESOURCES - the buffer cannot be locked at this time, but
+ * locking may succeed at a future time
+ * GRALLOC1_ERROR_UNSUPPORTED - the buffer cannot be locked with the given
+ * usage, and any future attempts at locking will also fail
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
+ uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
+ const gralloc1_rect_t* accessRegion, void** outData,
+ int32_t acquireFence);
+
+/* lockFlex(..., buffer, producerUsage, consumerUsage, accessRegion,
+ * outFlexLayout, outAcquireFence)
+ * Function descriptor: GRALLOC1_FUNCTION_LOCK_FLEX
+ * Must be provided by all gralloc1 devices
+ *
+ * This is largely the same as lock(), except that instead of returning a
+ * pointer directly to the buffer data, it returns an android_flex_layout
+ * struct describing how to access the data planes.
+ *
+ * This function must work on buffers with HAL_PIXEL_FORMAT_YCbCr_*_888 if
+ * supported by the device, as well as with any other formats requested by
+ * multimedia codecs when they are configured with a flexible-YUV-compatible
+ * color format.
+ *
+ * This function may also be called on buffers of other formats, including
+ * non-YUV formats, but if the buffer format is not compatible with a flexible
+ * representation, it may return GRALLOC1_ERROR_UNSUPPORTED.
+ *
+ * Parameters:
+ * buffer - the buffer to lock
+ * producerUsage - the producer usage flags to request; either this or
+ * consumerUsage must be GRALLOC1_*_USAGE_NONE, and the other must be a
+ * CPU usage
+ * consumerUsage - the consumer usage flags to request; either this or
+ * producerUsage must be GRALLOC1_*_USAGE_NONE, and the other must be a
+ * CPU usage
+ * accessRegion - the portion of the buffer that the client intends to access;
+ * must be non-NULL
+ * outFlexLayout - will be filled with the description of the planes in the
+ * buffer
+ * acquireFence - a sync fence file descriptor as described in lock()
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ * GRALLOC1_ERROR_BAD_VALUE - neither or both of producerUsage and
+ * consumerUsage were *_USAGE_NONE, or the usage which was not
+ * *_USAGE_NONE was not a CPU usage
+ * GRALLOC1_ERROR_NO_RESOURCES - the buffer cannot be locked at this time, but
+ * locking may succeed at a future time
+ * GRALLOC1_ERROR_UNSUPPORTED - the buffer cannot be locked with the given
+ * usage, and any future attempts at locking will also fail
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_LOCK_FLEX)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ uint64_t /*gralloc1_producer_usage_t*/ producerUsage,
+ uint64_t /*gralloc1_consumer_usage_t*/ consumerUsage,
+ const gralloc1_rect_t* accessRegion,
+ struct android_flex_layout* outFlexLayout, int32_t acquireFence);
+
+/* unlock(..., buffer, releaseFence)
+ * Function descriptor: GRALLOC1_FUNCTION_UNLOCK
+ * Must be provided by all gralloc1 devices
+ *
+ * This function indicates to the device that the client will be done with the
+ * buffer when releaseFence signals.
+ *
+ * outReleaseFence will be filled with a file descriptor referring to a release
+ * sync fence object, which will be signaled when it is safe to access the
+ * contents of the buffer (after the buffer has been unlocked). If it is already
+ * safe to access the buffer contents, then -1 may be returned instead.
+ *
+ * This function is used to unlock both buffers locked by lock() and those
+ * locked by lockFlex().
+ *
+ * Parameters:
+ * buffer - the buffer to unlock
+ * outReleaseFence - a sync fence file descriptor as described above
+ *
+ * Returns GRALLOC1_ERROR_NONE or one of the following errors:
+ * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid
+ */
+typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_UNLOCK)(
+ gralloc1_device_t* device, buffer_handle_t buffer,
+ int32_t* outReleaseFence);
+
+__END_DECLS
+
+#endif
diff --git a/include/hardware/power.h b/include/hardware/power.h
index c451d67..f15e3cd 100644
--- a/include/hardware/power.h
+++ b/include/hardware/power.h
@@ -63,7 +63,8 @@
POWER_HINT_VIDEO_DECODE = 0x00000004,
POWER_HINT_LOW_POWER = 0x00000005,
POWER_HINT_SUSTAINED_PERFORMANCE = 0x00000006,
- POWER_HINT_VR_MODE = 0x00000007
+ POWER_HINT_VR_MODE = 0x00000007,
+ POWER_HINT_LAUNCH = 0x00000008
} power_hint_t;
typedef enum {
diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c
index fe4a88e..6a3c5da 100644
--- a/modules/usbaudio/audio_hal.c
+++ b/modules/usbaudio/audio_hal.c
@@ -25,6 +25,7 @@
#include <sys/time.h>
#include <log/log.h>
+#include <cutils/list.h>
#include <cutils/str_parms.h>
#include <cutils/properties.h>
@@ -38,17 +39,6 @@
#include <audio_utils/channels.h>
-/* FOR TESTING:
- * Set k_force_channels to force the number of channels to present to AudioFlinger.
- * 0 disables (this is default: present the device channels to AudioFlinger).
- * 2 forces to legacy stereo mode.
- *
- * Others values can be tried (up to 8).
- * TODO: AudioFlinger cannot support more than 8 active output channels
- * at this time, so limiting logic needs to be put here or communicated from above.
- */
-static const unsigned k_force_channels = 0;
-
#include "alsa_device_profile.h"
#include "alsa_device_proxy.h"
#include "alsa_logging.h"
@@ -65,9 +55,11 @@
/* output */
alsa_device_profile out_profile;
+ struct listnode output_stream_list;
/* input */
alsa_device_profile in_profile;
+ struct listnode input_stream_list;
/* lock input & output sample rates */
/*FIXME - How do we address multiple output streams? */
@@ -78,14 +70,19 @@
bool standby;
};
+struct stream_lock {
+ pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
+};
+
struct stream_out {
struct audio_stream_out stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
+ struct stream_lock lock;
+
bool standby;
- struct audio_device *dev; /* hardware information - only using this for the lock */
+ struct audio_device *adev; /* hardware information - only using this for the lock */
alsa_device_profile * profile; /* Points to the alsa_device_profile in the audio_device */
alsa_device_proxy proxy; /* state of the stream */
@@ -95,7 +92,13 @@
* the device is not compatible with AudioFlinger
* capabilities, e.g. exposes too many channels or
* too few channels. */
- audio_channel_mask_t hal_channel_mask; /* channel mask exposed to AudioFlinger. */
+ audio_channel_mask_t hal_channel_mask; /* USB devices deal in channel counts, not masks
+ * so the proxy doesn't have a channel_mask, but
+ * audio HALs need to talk about channel masks
+ * so expose the one calculated by
+ * adev_open_output_stream */
+
+ struct listnode list_node;
void * conversion_buffer; /* any conversions are put into here
* they could come from here too if
@@ -106,11 +109,11 @@
struct stream_in {
struct audio_stream_in stream;
- pthread_mutex_t lock; /* see note below on mutex acquisition order */
- pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by capture thread */
+ struct stream_lock lock;
+
bool standby;
- struct audio_device *dev; /* hardware information - only using this for the lock */
+ struct audio_device *adev; /* hardware information - only using this for the lock */
alsa_device_profile * profile; /* Points to the alsa_device_profile in the audio_device */
alsa_device_proxy proxy; /* state of the stream */
@@ -120,7 +123,13 @@
* the device is not compatible with AudioFlinger
* capabilities, e.g. exposes too many channels or
* too few channels. */
- audio_channel_mask_t hal_channel_mask; /* channel mask exposed to AudioFlinger. */
+ audio_channel_mask_t hal_channel_mask; /* USB devices deal in channel counts, not masks
+ * so the proxy doesn't have a channel_mask, but
+ * audio HALs need to talk about channel masks
+ * so expose the one calculated by
+ * adev_open_input_stream */
+
+ struct listnode list_node;
/* We may need to read more data from the device in order to data reduce to 16bit, 4chan */
void * conversion_buffer; /* any conversions are put into here
@@ -130,12 +139,63 @@
};
/*
+ * Locking Helpers
+ */
+/*
* NOTE: when multiple mutexes have to be acquired, always take the
* stream_in or stream_out mutex first, followed by the audio_device mutex.
* stream pre_lock is always acquired before stream lock to prevent starvation of control thread by
* higher priority playback or capture thread.
*/
+static void stream_lock_init(struct stream_lock *lock) {
+ pthread_mutex_init(&lock->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&lock->pre_lock, (const pthread_mutexattr_t *) NULL);
+}
+
+static void stream_lock(struct stream_lock *lock) {
+ pthread_mutex_lock(&lock->pre_lock);
+ pthread_mutex_lock(&lock->lock);
+ pthread_mutex_unlock(&lock->pre_lock);
+}
+
+static void stream_unlock(struct stream_lock *lock) {
+ pthread_mutex_unlock(&lock->lock);
+}
+
+static void device_lock(struct audio_device *adev) {
+ pthread_mutex_lock(&adev->lock);
+}
+
+static int device_try_lock(struct audio_device *adev) {
+ return pthread_mutex_trylock(&adev->lock);
+}
+
+static void device_unlock(struct audio_device *adev) {
+ pthread_mutex_unlock(&adev->lock);
+}
+
+/*
+ * streams list management
+ */
+static void adev_add_stream_to_list(
+ struct audio_device* adev, struct listnode* list, struct listnode* stream_node) {
+ device_lock(adev);
+
+ list_add_tail(list, stream_node);
+
+ device_unlock(adev);
+}
+
+static void adev_remove_stream_from_list(
+ struct audio_device* adev, struct listnode* stream_node) {
+ device_lock(adev);
+
+ list_remove(stream_node);
+
+ device_unlock(adev);
+}
+
/*
* Extract the card and device numbers from the supplied key/value pairs.
* kvpairs A null-terminated string containing the key/value pairs or card and device.
@@ -214,20 +274,6 @@
return result_str;
}
-void lock_input_stream(struct stream_in *in)
-{
- pthread_mutex_lock(&in->pre_lock);
- pthread_mutex_lock(&in->lock);
- pthread_mutex_unlock(&in->pre_lock);
-}
-
-void lock_output_stream(struct stream_out *out)
-{
- pthread_mutex_lock(&out->pre_lock);
- pthread_mutex_lock(&out->lock);
- pthread_mutex_unlock(&out->pre_lock);
-}
-
/*
* HAl Functions
*/
@@ -285,20 +331,28 @@
{
struct stream_out *out = (struct stream_out *)stream;
- lock_output_stream(out);
+ stream_lock(&out->lock);
if (!out->standby) {
- pthread_mutex_lock(&out->dev->lock);
+ device_lock(out->adev);
proxy_close(&out->proxy);
- pthread_mutex_unlock(&out->dev->lock);
+ device_unlock(out->adev);
out->standby = true;
}
- pthread_mutex_unlock(&out->lock);
-
+ stream_unlock(&out->lock);
return 0;
}
-static int out_dump(const struct audio_stream *stream, int fd)
-{
+static int out_dump(const struct audio_stream *stream, int fd) {
+ const struct stream_out* out_stream = (const struct stream_out*) stream;
+
+ if (out_stream != NULL) {
+ dprintf(fd, "Output Profile:\n");
+ profile_dump(out_stream->profile, fd);
+
+ dprintf(fd, "Output Proxy:\n");
+ proxy_dump(&out_stream->proxy, fd);
+ }
+
return 0;
}
@@ -318,9 +372,9 @@
return ret_value;
}
- lock_output_stream(out);
+ stream_lock(&out->lock);
/* Lock the device because that is where the profile lives */
- pthread_mutex_lock(&out->dev->lock);
+ device_lock(out->adev);
if (!profile_is_cached_for(out->profile, card, device)) {
/* cannot read pcm device info if playback is active */
@@ -339,8 +393,8 @@
}
}
- pthread_mutex_unlock(&out->dev->lock);
- pthread_mutex_unlock(&out->lock);
+ device_unlock(out->adev);
+ stream_unlock(&out->lock);
return ret_value;
}
@@ -348,14 +402,13 @@
static char * out_get_parameters(const struct audio_stream *stream, const char *keys)
{
struct stream_out *out = (struct stream_out *)stream;
- lock_output_stream(out);
- pthread_mutex_lock(&out->dev->lock);
+ stream_lock(&out->lock);
+ device_lock(out->adev);
char * params_str = device_get_parameters(out->profile, keys);
- pthread_mutex_unlock(&out->lock);
- pthread_mutex_unlock(&out->dev->lock);
-
+ device_unlock(out->adev);
+ stream_unlock(&out->lock);
return params_str;
}
@@ -383,11 +436,11 @@
int ret;
struct stream_out *out = (struct stream_out *)stream;
- lock_output_stream(out);
+ stream_lock(&out->lock);
if (out->standby) {
- pthread_mutex_lock(&out->dev->lock);
+ device_lock(out->adev);
ret = start_output_stream(out);
- pthread_mutex_unlock(&out->dev->lock);
+ device_unlock(out->adev);
if (ret != 0) {
goto err;
}
@@ -422,12 +475,12 @@
proxy_write(&out->proxy, write_buff, num_write_buff_bytes);
}
- pthread_mutex_unlock(&out->lock);
+ stream_unlock(&out->lock);
return bytes;
err:
- pthread_mutex_unlock(&out->lock);
+ stream_unlock(&out->lock);
if (ret != 0) {
usleep(bytes * 1000000 / audio_stream_out_frame_size(stream) /
out_get_sample_rate(&stream->common));
@@ -445,12 +498,12 @@
uint64_t *frames, struct timespec *timestamp)
{
struct stream_out *out = (struct stream_out *)stream; // discard const qualifier
- lock_output_stream(out);
+ stream_lock(&out->lock);
const alsa_device_proxy *proxy = &out->proxy;
const int ret = proxy_get_presentation_position(proxy, frames, timestamp);
- pthread_mutex_unlock(&out->lock);
+ stream_unlock(&out->lock);
return ret;
}
@@ -469,24 +522,23 @@
return -EINVAL;
}
-static int adev_open_output_stream(struct audio_hw_device *dev,
+static int adev_open_output_stream(struct audio_hw_device *hw_dev,
audio_io_handle_t handle,
- audio_devices_t devices,
+ audio_devices_t devicesSpec __unused,
audio_output_flags_t flags,
struct audio_config *config,
struct audio_stream_out **stream_out,
const char *address /*__unused*/)
{
- ALOGV("adev_open_output_stream() handle:0x%X, device:0x%X, flags:0x%X, addr:%s",
- handle, devices, flags, address);
-
- struct audio_device *adev = (struct audio_device *)dev;
+ ALOGV("adev_open_output_stream() handle:0x%X, devicesSpec:0x%X, flags:0x%X, addr:%s",
+ handle, devicesSpec, flags, address);
struct stream_out *out;
out = (struct stream_out *)calloc(1, sizeof(struct stream_out));
- if (!out)
+ if (out == NULL) {
return -ENOMEM;
+ }
/* setup function pointers */
out->stream.common.get_sample_rate = out_get_sample_rate;
@@ -508,12 +560,11 @@
out->stream.get_presentation_position = out_get_presentation_position;
out->stream.get_next_write_timestamp = out_get_next_write_timestamp;
- pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
- pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
+ stream_lock_init(&out->lock);
- out->dev = adev;
- pthread_mutex_lock(&adev->lock);
- out->profile = &adev->out_profile;
+ out->adev = (struct audio_device *)hw_dev;
+ device_lock(out->adev);
+ out->profile = &out->adev->out_profile;
// build this to hand to the alsa_device_proxy
struct pcm_config proxy_config;
@@ -536,8 +587,8 @@
ret = -EINVAL;
}
- out->dev->device_sample_rate = config->sample_rate;
- pthread_mutex_unlock(&adev->lock);
+ out->adev->device_sample_rate = config->sample_rate;
+ device_unlock(out->adev);
/* Format */
if (config->format == AUDIO_FORMAT_DEFAULT) {
@@ -555,33 +606,38 @@
}
/* Channels */
- unsigned proposed_channel_count = 0;
- if (k_force_channels) {
- proposed_channel_count = k_force_channels;
- } else if (config->channel_mask == AUDIO_CHANNEL_NONE) {
- proposed_channel_count = profile_get_default_channel_count(out->profile);
- }
-
- if (proposed_channel_count != 0) {
- if (proposed_channel_count <= FCC_2) {
- // use channel position mask for mono and stereo
- config->channel_mask = audio_channel_out_mask_from_count(proposed_channel_count);
- } else {
- // use channel index mask for multichannel
- config->channel_mask =
- audio_channel_mask_for_index_assignment_from_count(proposed_channel_count);
- }
+ bool calc_mask = false;
+ if (config->channel_mask == AUDIO_CHANNEL_NONE) {
+ /* query case */
+ out->hal_channel_count = profile_get_default_channel_count(out->profile);
+ calc_mask = true;
} else {
- proposed_channel_count = audio_channel_count_from_out_mask(config->channel_mask);
+ /* explicit case */
+ out->hal_channel_count = audio_channel_count_from_out_mask(config->channel_mask);
}
- out->hal_channel_count = proposed_channel_count;
- /* we can expose any channel mask, and emulate internally based on channel count. */
+ /* The Framework is currently limited to no more than this number of channels */
+ if (out->hal_channel_count > FCC_8) {
+ out->hal_channel_count = FCC_8;
+ calc_mask = true;
+ }
+
+ if (calc_mask) {
+ /* need to calculate the mask from channel count either because this is the query case
+ * or the specified mask isn't valid for this device, or is more then the FW can handle */
+ config->channel_mask = out->hal_channel_count <= FCC_2
+ /* position mask for mono and stereo*/
+ ? audio_channel_out_mask_from_count(out->hal_channel_count)
+ /* otherwise indexed */
+ : audio_channel_mask_for_index_assignment_from_count(out->hal_channel_count);
+ }
+
out->hal_channel_mask = config->channel_mask;
- /* no validity checks are needed as proxy_prepare() forces channel_count to be valid.
- * and we emulate any channel count discrepancies in out_write(). */
- proxy_config.channels = out->hal_channel_count;
+ // Validate the "logical" channel count against support in the "actual" profile.
+ // if they differ, choose the "actual" number of channels *closest* to the "logical".
+ // and store THAT in proxy_config.channels
+ proxy_config.channels = profile_get_closest_channel_count(out->profile, out->hal_channel_count);
proxy_prepare(&out->proxy, out->profile, &proxy_config);
/* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger. */
@@ -592,6 +648,9 @@
out->standby = true;
+ /* Save the stream for adev_dump() */
+ adev_add_stream_to_list(out->adev, &out->adev->output_stream_list, &out->list_node);
+
*stream_out = &out->stream;
return ret;
@@ -602,12 +661,14 @@
return -ENOSYS;
}
-static void adev_close_output_stream(struct audio_hw_device *dev,
+static void adev_close_output_stream(struct audio_hw_device *hw_dev,
struct audio_stream_out *stream)
{
struct stream_out *out = (struct stream_out *)stream;
ALOGV("adev_close_output_stream(c:%d d:%d)", out->profile->card, out->profile->device);
+ adev_remove_stream_from_list(out->adev, &out->list_node);
+
/* Close the pcm device */
out_standby(&stream->common);
@@ -616,14 +677,14 @@
out->conversion_buffer = NULL;
out->conversion_buffer_size = 0;
- pthread_mutex_lock(&out->dev->lock);
- out->dev->device_sample_rate = 0;
- pthread_mutex_unlock(&out->dev->lock);
+ device_lock(out->adev);
+ out->adev->device_sample_rate = 0;
+ device_unlock(out->adev);
free(stream);
}
-static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev,
+static size_t adev_get_input_buffer_size(const struct audio_hw_device *hw_dev,
const struct audio_config *config)
{
/* TODO This needs to be calculated based on format/channels/rate */
@@ -676,22 +737,31 @@
{
struct stream_in *in = (struct stream_in *)stream;
- lock_input_stream(in);
+ stream_lock(&in->lock);
if (!in->standby) {
- pthread_mutex_lock(&in->dev->lock);
+ device_lock(in->adev);
proxy_close(&in->proxy);
- pthread_mutex_unlock(&in->dev->lock);
+ device_unlock(in->adev);
in->standby = true;
}
- pthread_mutex_unlock(&in->lock);
+ stream_unlock(&in->lock);
return 0;
}
static int in_dump(const struct audio_stream *stream, int fd)
{
- return 0;
+ const struct stream_in* in_stream = (const struct stream_in*)stream;
+ if (in_stream != NULL) {
+ dprintf(fd, "Input Profile:\n");
+ profile_dump(in_stream->profile, fd);
+
+ dprintf(fd, "Input Proxy:\n");
+ proxy_dump(&in_stream->proxy, fd);
+ }
+
+ return 0;
}
static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
@@ -712,8 +782,8 @@
return ret_value;
}
- lock_input_stream(in);
- pthread_mutex_lock(&in->dev->lock);
+ stream_lock(&in->lock);
+ device_lock(in->adev);
if (card >= 0 && device >= 0 && !profile_is_cached_for(in->profile, card, device)) {
/* cannot read pcm device info if playback is active */
@@ -732,8 +802,8 @@
}
}
- pthread_mutex_unlock(&in->dev->lock);
- pthread_mutex_unlock(&in->lock);
+ device_unlock(in->adev);
+ stream_unlock(&in->lock);
return ret_value;
}
@@ -742,13 +812,13 @@
{
struct stream_in *in = (struct stream_in *)stream;
- lock_input_stream(in);
- pthread_mutex_lock(&in->dev->lock);
+ stream_lock(&in->lock);
+ device_lock(in->adev);
char * params_str = device_get_parameters(in->profile, keys);
- pthread_mutex_unlock(&in->dev->lock);
- pthread_mutex_unlock(&in->lock);
+ device_unlock(in->adev);
+ stream_unlock(&in->lock);
return params_str;
}
@@ -786,11 +856,11 @@
struct stream_in * in = (struct stream_in *)stream;
- lock_input_stream(in);
+ stream_lock(&in->lock);
if (in->standby) {
- pthread_mutex_lock(&in->dev->lock);
+ device_lock(in->adev);
ret = start_input_stream(in);
- pthread_mutex_unlock(&in->dev->lock);
+ device_unlock(in->adev);
if (ret != 0) {
goto err;
}
@@ -840,16 +910,15 @@
}
}
- /* no need to acquire in->dev->lock to read mic_muted here as we don't change its state */
- if (num_read_buff_bytes > 0 && in->dev->mic_muted)
+ /* no need to acquire in->adev->lock to read mic_muted here as we don't change its state */
+ if (num_read_buff_bytes > 0 && in->adev->mic_muted)
memset(buffer, 0, num_read_buff_bytes);
} else {
num_read_buff_bytes = 0; // reset the value after USB headset is unplugged
}
err:
- pthread_mutex_unlock(&in->lock);
-
+ stream_unlock(&in->lock);
return num_read_buff_bytes;
}
@@ -858,9 +927,9 @@
return 0;
}
-static int adev_open_input_stream(struct audio_hw_device *dev,
+static int adev_open_input_stream(struct audio_hw_device *hw_dev,
audio_io_handle_t handle,
- audio_devices_t devices,
+ audio_devices_t devicesSpec __unused,
struct audio_config *config,
struct audio_stream_in **stream_in,
audio_input_flags_t flags __unused,
@@ -873,8 +942,9 @@
struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
int ret = 0;
- if (in == NULL)
+ if (in == NULL) {
return -ENOMEM;
+ }
/* setup function pointers */
in->stream.common.get_sample_rate = in_get_sample_rate;
@@ -894,13 +964,12 @@
in->stream.read = in_read;
in->stream.get_input_frames_lost = in_get_input_frames_lost;
- pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
- pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
+ stream_lock_init(&in->lock);
- in->dev = (struct audio_device *)dev;
- pthread_mutex_lock(&in->dev->lock);
+ in->adev = (struct audio_device *)hw_dev;
+ device_lock(in->adev);
- in->profile = &in->dev->in_profile;
+ in->profile = &in->adev->in_profile;
struct pcm_config proxy_config;
memset(&proxy_config, 0, sizeof(proxy_config));
@@ -915,17 +984,17 @@
config->sample_rate = profile_get_default_sample_rate(in->profile);
}
- if (in->dev->device_sample_rate != 0 && /* we are playing, so lock the rate */
- in->dev->device_sample_rate >= RATELOCK_THRESHOLD) {/* but only for high sample rates */
- ret = config->sample_rate != in->dev->device_sample_rate ? -EINVAL : 0;
- proxy_config.rate = config->sample_rate = in->dev->device_sample_rate;
+ if (in->adev->device_sample_rate != 0 && /* we are playing, so lock the rate */
+ in->adev->device_sample_rate >= RATELOCK_THRESHOLD) {/* but only for high sample rates */
+ ret = config->sample_rate != in->adev->device_sample_rate ? -EINVAL : 0;
+ proxy_config.rate = config->sample_rate = in->adev->device_sample_rate;
} else if (profile_is_sample_rate_valid(in->profile, config->sample_rate)) {
- in->dev->device_sample_rate = proxy_config.rate = config->sample_rate;
+ in->adev->device_sample_rate = proxy_config.rate = config->sample_rate;
} else {
proxy_config.rate = config->sample_rate = profile_get_default_sample_rate(in->profile);
ret = -EINVAL;
}
- pthread_mutex_unlock(&in->dev->lock);
+ device_unlock(in->adev);
/* Format */
if (config->format == AUDIO_FORMAT_DEFAULT) {
@@ -943,40 +1012,75 @@
}
/* Channels */
- unsigned proposed_channel_count = 0;
- if (k_force_channels) {
- proposed_channel_count = k_force_channels;
- } else if (config->channel_mask == AUDIO_CHANNEL_NONE) {
- proposed_channel_count = profile_get_default_channel_count(in->profile);
- }
- if (proposed_channel_count != 0) {
- config->channel_mask = audio_channel_in_mask_from_count(proposed_channel_count);
- if (config->channel_mask == AUDIO_CHANNEL_INVALID)
- config->channel_mask =
- audio_channel_mask_for_index_assignment_from_count(proposed_channel_count);
- in->hal_channel_count = proposed_channel_count;
+ bool calc_mask = false;
+ if (config->channel_mask == AUDIO_CHANNEL_NONE) {
+ /* query case */
+ in->hal_channel_count = profile_get_default_channel_count(in->profile);
+ calc_mask = true;
} else {
+ /* explicit case */
in->hal_channel_count = audio_channel_count_from_in_mask(config->channel_mask);
}
- /* we can expose any channel mask, and emulate internally based on channel count. */
- in->hal_channel_mask = config->channel_mask;
- proxy_config.channels = profile_get_default_channel_count(in->profile);
- proxy_prepare(&in->proxy, in->profile, &proxy_config);
+ /* The Framework is currently limited to no more than this number of channels */
+ if (in->hal_channel_count > FCC_8) {
+ in->hal_channel_count = FCC_8;
+ calc_mask = true;
+ }
- in->standby = true;
+ if (calc_mask) {
+ /* need to calculate the mask from channel count either because this is the query case
+ * or the specified mask isn't valid for this device, or is more then the FW can handle */
+ in->hal_channel_mask = in->hal_channel_count <= FCC_2
+ /* position mask for mono & stereo */
+ ? audio_channel_in_mask_from_count(in->hal_channel_count)
+ /* otherwise indexed */
+ : audio_channel_mask_for_index_assignment_from_count(in->hal_channel_count);
- in->conversion_buffer = NULL;
- in->conversion_buffer_size = 0;
+ // if we change the mask...
+ if (in->hal_channel_mask != config->channel_mask &&
+ config->channel_mask != AUDIO_CHANNEL_NONE) {
+ config->channel_mask = in->hal_channel_mask;
+ ret = -EINVAL;
+ }
+ } else {
+ in->hal_channel_mask = config->channel_mask;
+ }
- *stream_in = &in->stream;
+ if (ret == 0) {
+ // Validate the "logical" channel count against support in the "actual" profile.
+ // if they differ, choose the "actual" number of channels *closest* to the "logical".
+ // and store THAT in proxy_config.channels
+ proxy_config.channels =
+ profile_get_closest_channel_count(in->profile, in->hal_channel_count);
+ proxy_prepare(&in->proxy, in->profile, &proxy_config);
+
+ in->standby = true;
+
+ in->conversion_buffer = NULL;
+ in->conversion_buffer_size = 0;
+
+ *stream_in = &in->stream;
+
+ /* Save this for adev_dump() */
+ adev_add_stream_to_list(in->adev, &in->adev->input_stream_list, &in->list_node);
+ } else {
+ // Deallocate this stream on error, because AudioFlinger won't call
+ // adev_close_input_stream() in this case.
+ *stream_in = NULL;
+ free(in);
+ }
return ret;
}
-static void adev_close_input_stream(struct audio_hw_device *dev, struct audio_stream_in *stream)
+static void adev_close_input_stream(struct audio_hw_device *hw_dev,
+ struct audio_stream_in *stream)
{
struct stream_in *in = (struct stream_in *)stream;
+ ALOGV("adev_close_input_stream(c:%d d:%d)", in->profile->card, in->profile->device);
+
+ adev_remove_stream_from_list(in->adev, &in->list_node);
/* Close the pcm device */
in_standby(&stream->common);
@@ -989,52 +1093,94 @@
/*
* ADEV Functions
*/
-static int adev_set_parameters(struct audio_hw_device *dev, const char *kvpairs)
+static int adev_set_parameters(struct audio_hw_device *hw_dev, const char *kvpairs)
{
return 0;
}
-static char * adev_get_parameters(const struct audio_hw_device *dev, const char *keys)
+static char * adev_get_parameters(const struct audio_hw_device *hw_dev, const char *keys)
{
return strdup("");
}
-static int adev_init_check(const struct audio_hw_device *dev)
+static int adev_init_check(const struct audio_hw_device *hw_dev)
{
return 0;
}
-static int adev_set_voice_volume(struct audio_hw_device *dev, float volume)
+static int adev_set_voice_volume(struct audio_hw_device *hw_dev, float volume)
{
return -ENOSYS;
}
-static int adev_set_master_volume(struct audio_hw_device *dev, float volume)
+static int adev_set_master_volume(struct audio_hw_device *hw_dev, float volume)
{
return -ENOSYS;
}
-static int adev_set_mode(struct audio_hw_device *dev, audio_mode_t mode)
+static int adev_set_mode(struct audio_hw_device *hw_dev, audio_mode_t mode)
{
return 0;
}
-static int adev_set_mic_mute(struct audio_hw_device *dev, bool state)
+static int adev_set_mic_mute(struct audio_hw_device *hw_dev, bool state)
{
- struct audio_device * adev = (struct audio_device *)dev;
- pthread_mutex_lock(&adev->lock);
+ struct audio_device * adev = (struct audio_device *)hw_dev;
+ device_lock(adev);
adev->mic_muted = state;
- pthread_mutex_unlock(&adev->lock);
+ device_unlock(adev);
return -ENOSYS;
}
-static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state)
+static int adev_get_mic_mute(const struct audio_hw_device *hw_dev, bool *state)
{
return -ENOSYS;
}
-static int adev_dump(const audio_hw_device_t *device, int fd)
+static int adev_dump(const struct audio_hw_device *device, int fd)
{
+ dprintf(fd, "\nUSB audio module:\n");
+
+ struct audio_device* adev = (struct audio_device*)device;
+ const int kNumRetries = 3;
+ const int kSleepTimeMS = 500;
+
+ // use device_try_lock() in case we dumpsys during a deadlock
+ int retry = kNumRetries;
+ while (retry > 0 && device_try_lock(adev) != 0) {
+ sleep(kSleepTimeMS);
+ retry--;
+ }
+
+ if (retry > 0) {
+ if (list_empty(&adev->output_stream_list)) {
+ dprintf(fd, " No output streams.\n");
+ } else {
+ struct listnode* node;
+ list_for_each(node, &adev->output_stream_list) {
+ struct audio_stream* stream =
+ (struct audio_stream *)node_to_item(node, struct stream_out, list_node);
+ out_dump(stream, fd);
+ }
+ }
+
+ if (list_empty(&adev->input_stream_list)) {
+ dprintf(fd, "\n No input streams.\n");
+ } else {
+ struct listnode* node;
+ list_for_each(node, &adev->input_stream_list) {
+ struct audio_stream* stream =
+ (struct audio_stream *)node_to_item(node, struct stream_in, list_node);
+ in_dump(stream, fd);
+ }
+ }
+
+ device_unlock(adev);
+ } else {
+ // Couldn't lock
+ dprintf(fd, " Could not obtain device lock.\n");
+ }
+
return 0;
}
@@ -1058,6 +1204,9 @@
profile_init(&adev->out_profile, PCM_OUT);
profile_init(&adev->in_profile, PCM_IN);
+ list_init(&adev->output_stream_list);
+ list_init(&adev->input_stream_list);
+
adev->hw_device.common.tag = HARDWARE_DEVICE_TAG;
adev->hw_device.common.version = AUDIO_DEVICE_API_VERSION_2_0;
adev->hw_device.common.module = (struct hw_module_t *)module;