From b8811f080732fb360f640179f3034859fc9d540b Mon Sep 17 00:00:00 2001 From: Peng Xu Date: Thu, 10 Aug 2017 17:29:30 -0700 Subject: [PATCH 01/50] Proposing ownership for modules/sensors Test: n/a Change-Id: Ie5494af12686ae1bf0545e35ec8dcc00e21b2383 --- modules/sensors/OWNERS | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 modules/sensors/OWNERS diff --git a/modules/sensors/OWNERS b/modules/sensors/OWNERS new file mode 100644 index 00000000..1af35067 --- /dev/null +++ b/modules/sensors/OWNERS @@ -0,0 +1,2 @@ +pengxu@google.com +ashutoshj@google.com From eab6b6eda95192649c4c712755c8cab01b6c7f1a Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 11 Jul 2017 09:25:44 -0700 Subject: [PATCH 02/50] Use one type for UUID (2/5) Currently, we have few different representations for UUID in stack: tBT_UUID, tSDP_UUID, bt_uuid_t, bluetooth:UUID, or uint8_t*. Additionally, tBT_UUID and bt_uuid_t are used to hold UUID as 128bit as Little Endian or Big Endian, depending on which part of stack (GATT or SDP) is using it. This patch is creating one type, bluetooth::Uuid, that will replace all other types. Bug: 66912853 Test: all sl4a tests for GATT and RFCOMM Change-Id: Ic9048a6c1f32a16034485b6185f5349e6bac0ff6 --- include/hardware/ble_scanner.h | 4 +- include/hardware/bluetooth.h | 179 ++++++++++++++--------------- include/hardware/bt_common_types.h | 4 +- include/hardware/bt_gatt_client.h | 14 ++- include/hardware/bt_gatt_server.h | 4 +- include/hardware/bt_gatt_types.h | 4 +- include/hardware/bt_sdp.h | 12 +- include/hardware/bt_sock.h | 4 +- 8 files changed, 116 insertions(+), 109 deletions(-) diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h index 2d3ec82a..ddd251a6 100644 --- a/include/hardware/ble_scanner.h +++ b/include/hardware/ble_scanner.h @@ -88,8 +88,8 @@ class BleScannerInterface { /** Configure a scan filter condition */ virtual void ScanFilterAddRemove(int action, int filt_type, int filt_index, int company_id, int company_id_mask, - const bt_uuid_t *p_uuid, - const bt_uuid_t *p_uuid_mask, + const bluetooth::Uuid *p_uuid, + const bluetooth::Uuid *p_uuid_mask, const RawAddress *bd_addr, char addr_type, std::vector data, std::vector p_mask, diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h index f57872d3..d6f6e3e9 100644 --- a/include/hardware/bluetooth.h +++ b/include/hardware/bluetooth.h @@ -24,6 +24,7 @@ #include +#include #include __BEGIN_DECLS @@ -127,15 +128,10 @@ typedef enum { BT_ACL_STATE_DISCONNECTED } bt_acl_state_t; -/** Bluetooth 128-bit UUID */ -typedef struct { - uint8_t uu[16]; -} bt_uuid_t; - /** Bluetooth SDP service record */ typedef struct { - bt_uuid_t uuid; + bluetooth::Uuid uuid; uint16_t channel; char name[256]; // what's the maximum length } bt_service_record_t; @@ -171,94 +167,95 @@ typedef struct /* Bluetooth Adapter and Remote Device property types */ typedef enum { - /* Properties common to both adapter and remote device */ - /** - * Description - Bluetooth Device Name - * Access mode - Adapter name can be GET/SET. Remote device can be GET - * Data type - bt_bdname_t - */ - BT_PROPERTY_BDNAME = 0x1, - /** - * Description - Bluetooth Device Address - * Access mode - Only GET. - * Data type - RawAddress - */ - BT_PROPERTY_BDADDR, - /** - * Description - Bluetooth Service 128-bit UUIDs - * Access mode - Only GET. - * Data type - Array of bt_uuid_t (Array size inferred from property length). - */ - BT_PROPERTY_UUIDS, - /** - * Description - Bluetooth Class of Device as found in Assigned Numbers - * Access mode - Only GET. - * Data type - uint32_t. - */ - BT_PROPERTY_CLASS_OF_DEVICE, - /** - * Description - Device Type - BREDR, BLE or DUAL Mode - * Access mode - Only GET. - * Data type - bt_device_type_t - */ - BT_PROPERTY_TYPE_OF_DEVICE, - /** - * Description - Bluetooth Service Record - * Access mode - Only GET. - * Data type - bt_service_record_t - */ - BT_PROPERTY_SERVICE_RECORD, + /* Properties common to both adapter and remote device */ + /** + * Description - Bluetooth Device Name + * Access mode - Adapter name can be GET/SET. Remote device can be GET + * Data type - bt_bdname_t + */ + BT_PROPERTY_BDNAME = 0x1, + /** + * Description - Bluetooth Device Address + * Access mode - Only GET. + * Data type - RawAddress + */ + BT_PROPERTY_BDADDR, + /** + * Description - Bluetooth Service 128-bit UUIDs + * Access mode - Only GET. + * Data type - Array of bluetooth::Uuid (Array size inferred from property + * length). + */ + BT_PROPERTY_UUIDS, + /** + * Description - Bluetooth Class of Device as found in Assigned Numbers + * Access mode - Only GET. + * Data type - uint32_t. + */ + BT_PROPERTY_CLASS_OF_DEVICE, + /** + * Description - Device Type - BREDR, BLE or DUAL Mode + * Access mode - Only GET. + * Data type - bt_device_type_t + */ + BT_PROPERTY_TYPE_OF_DEVICE, + /** + * Description - Bluetooth Service Record + * Access mode - Only GET. + * Data type - bt_service_record_t + */ + BT_PROPERTY_SERVICE_RECORD, - /* Properties unique to adapter */ - /** - * Description - Bluetooth Adapter scan mode - * Access mode - GET and SET - * Data type - bt_scan_mode_t. - */ - BT_PROPERTY_ADAPTER_SCAN_MODE, - /** - * Description - List of bonded devices - * Access mode - Only GET. - * Data type - Array of RawAddress of the bonded remote devices - * (Array size inferred from property length). - */ - BT_PROPERTY_ADAPTER_BONDED_DEVICES, - /** - * Description - Bluetooth Adapter Discovery timeout (in seconds) - * Access mode - GET and SET - * Data type - uint32_t - */ - BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, + /* Properties unique to adapter */ + /** + * Description - Bluetooth Adapter scan mode + * Access mode - GET and SET + * Data type - bt_scan_mode_t. + */ + BT_PROPERTY_ADAPTER_SCAN_MODE, + /** + * Description - List of bonded devices + * Access mode - Only GET. + * Data type - Array of RawAddress of the bonded remote devices + * (Array size inferred from property length). + */ + BT_PROPERTY_ADAPTER_BONDED_DEVICES, + /** + * Description - Bluetooth Adapter Discovery timeout (in seconds) + * Access mode - GET and SET + * Data type - uint32_t + */ + BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT, - /* Properties unique to remote device */ - /** - * Description - User defined friendly name of the remote device - * Access mode - GET and SET - * Data type - bt_bdname_t. - */ - BT_PROPERTY_REMOTE_FRIENDLY_NAME, - /** - * Description - RSSI value of the inquired remote device - * Access mode - Only GET. - * Data type - int32_t. - */ - BT_PROPERTY_REMOTE_RSSI, - /** - * Description - Remote version info - * Access mode - SET/GET. - * Data type - bt_remote_version_t. - */ + /* Properties unique to remote device */ + /** + * Description - User defined friendly name of the remote device + * Access mode - GET and SET + * Data type - bt_bdname_t. + */ + BT_PROPERTY_REMOTE_FRIENDLY_NAME, + /** + * Description - RSSI value of the inquired remote device + * Access mode - Only GET. + * Data type - int32_t. + */ + BT_PROPERTY_REMOTE_RSSI, + /** + * Description - Remote version info + * Access mode - SET/GET. + * Data type - bt_remote_version_t. + */ - BT_PROPERTY_REMOTE_VERSION_INFO, + BT_PROPERTY_REMOTE_VERSION_INFO, - /** - * Description - Local LE features - * Access mode - GET. - * Data type - bt_local_le_features_t. - */ - BT_PROPERTY_LOCAL_LE_FEATURES, + /** + * Description - Local LE features + * Access mode - GET. + * Data type - bt_local_le_features_t. + */ + BT_PROPERTY_LOCAL_LE_FEATURES, - BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, + BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP = 0xFF, } bt_property_type_t; /** Bluetooth Adapter Property data structure */ @@ -501,8 +498,8 @@ typedef struct { const bt_property_t *property); /** Get Remote Device's service record for the given UUID */ - int (*get_remote_service_record)(RawAddress *remote_addr, - bt_uuid_t *uuid); + int (*get_remote_service_record)(const RawAddress& remote_addr, + const bluetooth::Uuid& uuid); /** Start SDP to get remote services */ int (*get_remote_services)(RawAddress *remote_addr); diff --git a/include/hardware/bt_common_types.h b/include/hardware/bt_common_types.h index 8d13ed45..1deae27a 100644 --- a/include/hardware/bt_common_types.h +++ b/include/hardware/bt_common_types.h @@ -24,6 +24,8 @@ #include "bluetooth.h" +#include + typedef struct { uint8_t client_if; @@ -53,7 +55,7 @@ typedef enum typedef struct { uint16_t id; - bt_uuid_t uuid; + bluetooth::Uuid uuid; bt_gatt_db_attribute_type_t type; uint16_t attribute_handle; diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h index cafc2da7..1ec97447 100644 --- a/include/hardware/bt_gatt_client.h +++ b/include/hardware/bt_gatt_client.h @@ -23,6 +23,8 @@ #include "bt_gatt_types.h" #include "bt_common_types.h" +#include + __BEGIN_DECLS /** @@ -69,7 +71,7 @@ typedef struct typedef struct { RawAddress *bda1; - bt_uuid_t *uuid1; + bluetooth::Uuid *uuid1; uint16_t u1; uint16_t u2; uint16_t u3; @@ -99,7 +101,7 @@ typedef enum /** BT-GATT Client callback structure. */ /** Callback invoked in response to register_client */ -typedef void (*register_client_callback)(int status, int client_if, const bt_uuid_t& app_uuid); +typedef void (*register_client_callback)(int status, int client_if, const bluetooth::Uuid& app_uuid); /** GATT open callback invoked in response to open */ typedef void (*connect_callback)(int conn_id, int status, int client_if, const RawAddress& bda); @@ -200,7 +202,7 @@ typedef struct { typedef struct { /** Registers a GATT client application with the stack */ - bt_status_t (*register_client)(const bt_uuid_t& uuid); + bt_status_t (*register_client)(const bluetooth::Uuid& uuid); /** Unregister a client application from the stack */ bt_status_t (*unregister_client)(int client_if); @@ -221,12 +223,12 @@ typedef struct { * Enumerate all GATT services on a connected device. * Optionally, the results can be filtered for a given UUID. */ - bt_status_t (*search_service)(int conn_id, const bt_uuid_t *filter_uuid); + bt_status_t (*search_service)(int conn_id, const bluetooth::Uuid *filter_uuid); /** * Sead "Find service by UUID" request. Used only for PTS tests. */ - void (*btif_gattc_discover_service_by_uuid)(int conn_id, const bt_uuid_t& uuid); + void (*btif_gattc_discover_service_by_uuid)(int conn_id, const bluetooth::Uuid& uuid); /** Read a characteristic on a remote device */ bt_status_t (*read_characteristic)(int conn_id, uint16_t handle, @@ -234,7 +236,7 @@ typedef struct { /** Read a characteristic on a remote device */ bt_status_t (*read_using_characteristic_uuid)( - int conn_id, const bt_uuid_t& uuid, uint16_t s_handle, + int conn_id, const bluetooth::Uuid& uuid, uint16_t s_handle, uint16_t e_handle, int auth_req); /** Write a remote characteristic */ diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h index 93ecc025..0a9cb9f5 100644 --- a/include/hardware/bt_gatt_server.h +++ b/include/hardware/bt_gatt_server.h @@ -46,7 +46,7 @@ typedef union /** Callback invoked in response to register_server */ typedef void (*register_server_callback)(int status, int server_if, - const bt_uuid_t& app_uuid); + const bluetooth::Uuid& app_uuid); /** Callback indicating that a remote device has connected or been disconnected */ typedef void (*connection_callback)(int conn_id, int server_if, int connected, @@ -135,7 +135,7 @@ typedef struct { /** Represents the standard BT-GATT server interface. */ typedef struct { /** Registers a GATT server application with the stack */ - bt_status_t (*register_server)(const bt_uuid_t& uuid); + bt_status_t (*register_server)(const bluetooth::Uuid& uuid); /** Unregister a server application from the stack */ bt_status_t (*unregister_server)(int server_if ); diff --git a/include/hardware/bt_gatt_types.h b/include/hardware/bt_gatt_types.h index e037ddcd..7130c171 100644 --- a/include/hardware/bt_gatt_types.h +++ b/include/hardware/bt_gatt_types.h @@ -21,6 +21,8 @@ #include #include +#include + __BEGIN_DECLS /** @@ -32,7 +34,7 @@ __BEGIN_DECLS /** GATT ID adding instance id tracking to the UUID */ typedef struct { - bt_uuid_t uuid; + bluetooth::Uuid uuid; uint8_t inst_id; } btgatt_gatt_id_t; diff --git a/include/hardware/bt_sdp.h b/include/hardware/bt_sdp.h index 76cb5798..7db71394 100644 --- a/include/hardware/bt_sdp.h +++ b/include/hardware/bt_sdp.h @@ -37,7 +37,7 @@ typedef enum { typedef struct _bluetooth_sdp_hdr { bluetooth_sdp_types type; - bt_uuid_t uuid; + bluetooth::Uuid uuid; uint32_t service_name_length; char *service_name; int32_t rfcomm_channel_number; @@ -51,7 +51,7 @@ typedef struct _bluetooth_sdp_hdr { */ typedef struct _bluetooth_sdp_hdr_overlay { bluetooth_sdp_types type; - bt_uuid_t uuid; + bluetooth::Uuid uuid; uint32_t service_name_length; char *service_name; int32_t rfcomm_channel_number; @@ -109,7 +109,11 @@ typedef union { /** Callback for SDP search */ -typedef void (*btsdp_search_callback)(bt_status_t status, RawAddress *bd_addr, uint8_t* uuid, int num_records, bluetooth_sdp_record *records); +typedef void (*btsdp_search_callback)(bt_status_t status, + const RawAddress &bd_addr, + const bluetooth::Uuid &uuid, + int num_records, + bluetooth_sdp_record *records); typedef struct { /** Set to sizeof(btsdp_callbacks_t) */ @@ -128,7 +132,7 @@ typedef struct { bt_status_t (*deinit)(); /** Search for SDP records with specific uuid on remote device */ - bt_status_t (*sdp_search)(RawAddress *bd_addr, const uint8_t* uuid); + bt_status_t (*sdp_search)(RawAddress *bd_addr, const bluetooth::Uuid& uuid); /** * Use listen in the socket interface to create rfcomm and/or l2cap PSM channels, diff --git a/include/hardware/bt_sock.h b/include/hardware/bt_sock.h index 4c098f1f..70161a3f 100644 --- a/include/hardware/bt_sock.h +++ b/include/hardware/bt_sock.h @@ -60,7 +60,7 @@ typedef struct { * used for traffic accounting purposes. */ bt_status_t (*listen)(btsock_type_t type, const char* service_name, - const uint8_t* service_uuid, int channel, int* sock_fd, int flags, int callingUid); + const bluetooth::Uuid* service_uuid, int channel, int* sock_fd, int flags, int callingUid); /** * Connect to a RFCOMM UUID channel of remote device, It returns the socket fd from which @@ -68,7 +68,7 @@ typedef struct { * The callingUid is the UID of the application which is requesting the socket. This is * used for traffic accounting purposes. */ - bt_status_t (*connect)(const RawAddress *bd_addr, btsock_type_t type, const uint8_t* uuid, + bt_status_t (*connect)(const RawAddress *bd_addr, btsock_type_t type, const bluetooth::Uuid* uuid, int channel, int* sock_fd, int flags, int callingUid); } btsock_interface_t; From 81895aad176e4581cc363f8e8528a1669781837a Mon Sep 17 00:00:00 2001 From: Dan Albert Date: Thu, 12 Oct 2017 13:31:52 -0700 Subject: [PATCH 03/50] Add missing includes. Change-Id: Id6a97bfdb28f155f691891c746cbc1008e6ce083 Exempt-From-Owner-Approval: trivial cleanup Test: mma Bug: None --- modules/camera/3_0/Metadata.cpp | 2 ++ modules/usbcamera/Metadata.cpp | 2 ++ 2 files changed, 4 insertions(+) diff --git a/modules/camera/3_0/Metadata.cpp b/modules/camera/3_0/Metadata.cpp index 440da5f8..9b8eb1d3 100644 --- a/modules/camera/3_0/Metadata.cpp +++ b/modules/camera/3_0/Metadata.cpp @@ -16,6 +16,8 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "Metadata" +#include + #include #include diff --git a/modules/usbcamera/Metadata.cpp b/modules/usbcamera/Metadata.cpp index 78318f39..b0d2f93d 100644 --- a/modules/usbcamera/Metadata.cpp +++ b/modules/usbcamera/Metadata.cpp @@ -17,6 +17,8 @@ //#define LOG_NDEBUG 0 #define LOG_TAG "Metadata" +#include + #include #define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL) From 5d5996a069c51556d6d0e7b1090061889e7c2b67 Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Mon, 16 Oct 2017 20:10:09 -0700 Subject: [PATCH 04/50] Remove hw_module_t dependency in Bluetooth (2/3) Bug: 67853426 Test: run Bluetooth Change-Id: I0b144544b99a4e7fea74800d3bd44b45f446d02f --- include/hardware/bluetooth.h | 22 +--------------------- include/hardware/hardware.h | 2 -- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/include/hardware/bluetooth.h b/include/hardware/bluetooth.h index d6f6e3e9..40ccc604 100644 --- a/include/hardware/bluetooth.h +++ b/include/hardware/bluetooth.h @@ -22,20 +22,12 @@ #include #include -#include - #include #include __BEGIN_DECLS -/** - * The Bluetooth Hardware Module ID - */ - -#define BT_HARDWARE_MODULE_ID "bluetooth" -#define BT_STACK_MODULE_ID "bluetooth" - +#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface" /** Bluetooth profile interface IDs */ @@ -592,18 +584,6 @@ typedef struct { void (*interop_database_add)(uint16_t feature, const RawAddress *addr, size_t len); } bt_interface_t; -/** TODO: Need to add APIs for Service Discovery, Service authorization and - * connection management. Also need to add APIs for configuring - * properties of remote bonded devices such as name, UUID etc. */ - -typedef struct { - struct hw_device_t common; - const bt_interface_t* (*get_bluetooth_interface)(); -} bluetooth_device_t; - -typedef bluetooth_device_t bluetooth_module_t; - - __END_DECLS #endif /* ANDROID_INCLUDE_BLUETOOTH_H */ diff --git a/include/hardware/hardware.h b/include/hardware/hardware.h index 5ba37e92..bf076f6c 100644 --- a/include/hardware/hardware.h +++ b/include/hardware/hardware.h @@ -20,10 +20,8 @@ #include #include -#ifndef _HW_DONT_INCLUDE_CORE_ #include #include -#endif // _HW_DONT_INCLUDE_CORE_ __BEGIN_DECLS From 4d64b603db61fb53c10a6fadceca259a6e0093cc Mon Sep 17 00:00:00 2001 From: Jakub Pawlowski Date: Tue, 17 Oct 2017 16:00:33 -0700 Subject: [PATCH 05/50] Move Bluetooth headers to system/bt (2/3) Bug: 67853426 Test: run Bluetooth Change-Id: If99fc83e08294cfc26608dcef88a5c3836d88863 --- include/hardware/ble_advertiser.h | 108 ----- include/hardware/ble_scanner.h | 139 ------ include/hardware/bt_av.h | 242 ----------- include/hardware/bt_common_types.h | 93 ----- include/hardware/bt_gatt.h | 72 ---- include/hardware/bt_gatt_client.h | 299 ------------- include/hardware/bt_gatt_server.h | 181 -------- include/hardware/bt_gatt_types.h | 58 --- include/hardware/bt_hd.h | 127 ------ include/hardware/bt_hf.h | 333 --------------- include/hardware/bt_hf_client.h | 383 ----------------- include/hardware/bt_hh.h | 191 --------- include/hardware/bt_hl.h | 123 ------ include/hardware/bt_mce.h | 54 --- include/hardware/bt_pan.h | 87 ---- include/hardware/bt_rc.h | 649 ----------------------------- include/hardware/bt_sdp.h | 154 ------- include/hardware/bt_sock.h | 76 ---- 18 files changed, 3369 deletions(-) delete mode 100644 include/hardware/ble_advertiser.h delete mode 100644 include/hardware/ble_scanner.h delete mode 100644 include/hardware/bt_av.h delete mode 100644 include/hardware/bt_common_types.h delete mode 100644 include/hardware/bt_gatt.h delete mode 100644 include/hardware/bt_gatt_client.h delete mode 100644 include/hardware/bt_gatt_server.h delete mode 100644 include/hardware/bt_gatt_types.h delete mode 100644 include/hardware/bt_hd.h delete mode 100644 include/hardware/bt_hf.h delete mode 100644 include/hardware/bt_hf_client.h delete mode 100644 include/hardware/bt_hh.h delete mode 100644 include/hardware/bt_hl.h delete mode 100644 include/hardware/bt_mce.h delete mode 100644 include/hardware/bt_pan.h delete mode 100644 include/hardware/bt_rc.h delete mode 100644 include/hardware/bt_sdp.h delete mode 100644 include/hardware/bt_sock.h diff --git a/include/hardware/ble_advertiser.h b/include/hardware/ble_advertiser.h deleted file mode 100644 index 5284800c..00000000 --- a/include/hardware/ble_advertiser.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * 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 ANDROID_INCLUDE_BLE_ADVERTISER_H -#define ANDROID_INCLUDE_BLE_ADVERTISER_H - -#include -#include -#include -#include "bt_common_types.h" -#include "bt_gatt_types.h" - -struct AdvertiseParameters { - uint16_t advertising_event_properties; - uint32_t min_interval; - uint32_t max_interval; - uint8_t channel_map; - int8_t tx_power; - uint8_t primary_advertising_phy; - uint8_t secondary_advertising_phy; - uint8_t scan_request_notification_enable; -}; - -struct PeriodicAdvertisingParameters { - uint8_t enable; - uint16_t min_interval; - uint16_t max_interval; - uint16_t periodic_advertising_properties; -}; - -class BleAdvertiserInterface { - public: - virtual ~BleAdvertiserInterface() = default; - - /** Callback invoked when multi-adv operation has completed */ - using StatusCallback = base::Callback; - using IdStatusCallback = - base::Callback; - using IdTxPowerStatusCallback = - base::Callback; - using ParametersCallback = - base::Callback; - - /** Registers an advertiser with the stack */ - virtual void RegisterAdvertiser(IdStatusCallback) = 0; - - using GetAddressCallback = base::Callback; - virtual void GetOwnAddress(uint8_t advertiser_id, GetAddressCallback cb) = 0; - - /* Set the parameters as per spec, user manual specified values */ - virtual void SetParameters(uint8_t advertiser_id, AdvertiseParameters params, - ParametersCallback cb) = 0; - - /* Setup the data */ - virtual void SetData(int advertiser_id, bool set_scan_rsp, - std::vector data, StatusCallback cb) = 0; - - /* Enable the advertising instance */ - virtual void Enable(uint8_t advertiser_id, bool enable, StatusCallback cb, - uint16_t duration, uint8_t maxExtAdvEvents, - StatusCallback timeout_cb) = 0; - - /* Unregisters an advertiser */ - virtual void Unregister(uint8_t advertiser_id) = 0; - - virtual void StartAdvertising(uint8_t advertiser_id, StatusCallback cb, - AdvertiseParameters params, - std::vector advertise_data, - std::vector scan_response_data, - int timeout_s, StatusCallback timeout_cb) = 0; - - /** Start the advertising set. This include registering, setting all - * parameters and data, and enabling it. |register_cb| is called when the set - * is advertising. |timeout_cb| is called when the timeout_s have passed */ - virtual void StartAdvertisingSet( - IdTxPowerStatusCallback register_cb, AdvertiseParameters params, - std::vector advertise_data, - std::vector scan_response_data, - PeriodicAdvertisingParameters periodic_params, - std::vector periodic_data, uint16_t duration, - uint8_t maxExtAdvEvents, IdStatusCallback timeout_cb) = 0; - - virtual void SetPeriodicAdvertisingParameters( - int advertiser_id, PeriodicAdvertisingParameters parameters, - StatusCallback cb) = 0; - - virtual void SetPeriodicAdvertisingData(int advertiser_id, - std::vector data, - StatusCallback cb) = 0; - - virtual void SetPeriodicAdvertisingEnable(int advertiser_id, bool enable, - StatusCallback cb) = 0; -}; - -#endif /* ANDROID_INCLUDE_BLE_ADVERTISER_H */ diff --git a/include/hardware/ble_scanner.h b/include/hardware/ble_scanner.h deleted file mode 100644 index ddd251a6..00000000 --- a/include/hardware/ble_scanner.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * 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 ANDROID_INCLUDE_BLE_SCANNER_H -#define ANDROID_INCLUDE_BLE_SCANNER_H - -#include -#include -#include "bt_common_types.h" -#include "bt_gatt_client.h" -#include "bt_gatt_types.h" - -/** Callback invoked when batchscan reports are obtained */ -typedef void (*batchscan_reports_callback)(int client_if, int status, - int report_format, int num_records, - std::vector data); - -/** Callback invoked when batchscan storage threshold limit is crossed */ -typedef void (*batchscan_threshold_callback)(int client_if); - -/** Track ADV VSE callback invoked when tracked device is found or lost */ -typedef void (*track_adv_event_callback)( - btgatt_track_adv_info_t *p_track_adv_info); - -/** Callback for scan results */ -typedef void (*scan_result_callback)(uint16_t event_type, uint8_t addr_type, - RawAddress *bda, uint8_t primary_phy, - uint8_t secondary_phy, - uint8_t advertising_sid, int8_t tx_power, - int8_t rssi, uint16_t periodic_adv_int, - std::vector adv_data); - -typedef struct { - scan_result_callback scan_result_cb; - batchscan_reports_callback batchscan_reports_cb; - batchscan_threshold_callback batchscan_threshold_cb; - track_adv_event_callback track_adv_event_cb; -} btgatt_scanner_callbacks_t; - -class BleScannerInterface { - public: - virtual ~BleScannerInterface() = default; - - using RegisterCallback = - base::Callback; - - using Callback = base::Callback; - - using EnableCallback = - base::Callback; - - using FilterParamSetupCallback = - base::Callback; - - using FilterConfigCallback = - base::Callback; - - /** Registers a scanner with the stack */ - virtual void RegisterScanner(RegisterCallback) = 0; - - /** Unregister a scanner from the stack */ - virtual void Unregister(int scanner_id) = 0; - - /** Start or stop LE device scanning */ - virtual void Scan(bool start) = 0; - - /** Setup scan filter params */ - virtual void ScanFilterParamSetup( - uint8_t client_if, uint8_t action, uint8_t filt_index, - std::unique_ptr filt_param, - FilterParamSetupCallback cb) = 0; - - /** Configure a scan filter condition */ - virtual void ScanFilterAddRemove(int action, int filt_type, int filt_index, - int company_id, int company_id_mask, - const bluetooth::Uuid *p_uuid, - const bluetooth::Uuid *p_uuid_mask, - const RawAddress *bd_addr, char addr_type, - std::vector data, - std::vector p_mask, - FilterConfigCallback cb) = 0; - - /** Clear all scan filter conditions for specific filter index*/ - virtual void ScanFilterClear(int filt_index, FilterConfigCallback cb) = 0; - - /** Enable / disable scan filter feature*/ - virtual void ScanFilterEnable(bool enable, EnableCallback cb) = 0; - - /** Sets the LE scan interval and window in units of N*0.625 msec */ - virtual void SetScanParameters(int scan_interval, int scan_window, - Callback cb) = 0; - - /* Configure the batchscan storage */ - virtual void BatchscanConfigStorage(int client_if, int batch_scan_full_max, - int batch_scan_trunc_max, - int batch_scan_notify_threshold, - Callback cb) = 0; - - /* Enable batchscan */ - virtual void BatchscanEnable(int scan_mode, int scan_interval, - int scan_window, int addr_type, int discard_rule, - Callback cb) = 0; - - /* Disable batchscan */ - virtual void BatchscanDisable(Callback cb) = 0; - - /* Read out batchscan reports */ - virtual void BatchscanReadReports(int client_if, int scan_mode) = 0; - - using StartSyncCb = - base::Callback; - using SyncReportCb = - base::Callback data)>; - using SyncLostCb = base::Callback; - virtual void StartSync(uint8_t sid, RawAddress address, uint16_t skip, - uint16_t timeout, StartSyncCb start_cb, - SyncReportCb report_cb, SyncLostCb lost_cb) = 0; - virtual void StopSync(uint16_t handle) = 0; -}; - -#endif /* ANDROID_INCLUDE_BLE_SCANNER_H */ \ No newline at end of file diff --git a/include/hardware/bt_av.h b/include/hardware/bt_av.h deleted file mode 100644 index 36722d43..00000000 --- a/include/hardware/bt_av.h +++ /dev/null @@ -1,242 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_AV_H -#define ANDROID_INCLUDE_BT_AV_H - -#include - -#include - -__BEGIN_DECLS - -/* Bluetooth AV connection states */ -typedef enum { - BTAV_CONNECTION_STATE_DISCONNECTED = 0, - BTAV_CONNECTION_STATE_CONNECTING, - BTAV_CONNECTION_STATE_CONNECTED, - BTAV_CONNECTION_STATE_DISCONNECTING -} btav_connection_state_t; - -/* Bluetooth AV datapath states */ -typedef enum { - BTAV_AUDIO_STATE_REMOTE_SUSPEND = 0, - BTAV_AUDIO_STATE_STOPPED, - BTAV_AUDIO_STATE_STARTED, -} btav_audio_state_t; - -/* - * Enum values for each A2DP supported codec. - * There should be a separate entry for each A2DP codec that is supported - * for encoding (SRC), and for decoding purpose (SINK). - */ -typedef enum { - BTAV_A2DP_CODEC_INDEX_SOURCE_MIN = 0, - - // Add an entry for each source codec here. - // NOTE: The values should be same as those listed in the following file: - // BluetoothCodecConfig.java - BTAV_A2DP_CODEC_INDEX_SOURCE_SBC = 0, - BTAV_A2DP_CODEC_INDEX_SOURCE_AAC, - BTAV_A2DP_CODEC_INDEX_SOURCE_APTX, - BTAV_A2DP_CODEC_INDEX_SOURCE_APTX_HD, - BTAV_A2DP_CODEC_INDEX_SOURCE_LDAC, - - BTAV_A2DP_CODEC_INDEX_SOURCE_MAX, - - BTAV_A2DP_CODEC_INDEX_SINK_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MAX, - - // Add an entry for each sink codec here - BTAV_A2DP_CODEC_INDEX_SINK_SBC = BTAV_A2DP_CODEC_INDEX_SINK_MIN, - - BTAV_A2DP_CODEC_INDEX_SINK_MAX, - - BTAV_A2DP_CODEC_INDEX_MIN = BTAV_A2DP_CODEC_INDEX_SOURCE_MIN, - BTAV_A2DP_CODEC_INDEX_MAX = BTAV_A2DP_CODEC_INDEX_SINK_MAX -} btav_a2dp_codec_index_t; - -typedef enum { - // Disable the codec. - // NOTE: This value can be used only during initialization when - // function btav_source_interface_t::init() is called. - BTAV_A2DP_CODEC_PRIORITY_DISABLED = -1, - - // Reset the codec priority to its default value. - BTAV_A2DP_CODEC_PRIORITY_DEFAULT = 0, - - // Highest codec priority. - BTAV_A2DP_CODEC_PRIORITY_HIGHEST = 1000 * 1000 -} btav_a2dp_codec_priority_t; - -typedef enum { - BTAV_A2DP_CODEC_SAMPLE_RATE_NONE = 0x0, - BTAV_A2DP_CODEC_SAMPLE_RATE_44100 = 0x1 << 0, - BTAV_A2DP_CODEC_SAMPLE_RATE_48000 = 0x1 << 1, - BTAV_A2DP_CODEC_SAMPLE_RATE_88200 = 0x1 << 2, - BTAV_A2DP_CODEC_SAMPLE_RATE_96000 = 0x1 << 3, - BTAV_A2DP_CODEC_SAMPLE_RATE_176400 = 0x1 << 4, - BTAV_A2DP_CODEC_SAMPLE_RATE_192000 = 0x1 << 5 -} btav_a2dp_codec_sample_rate_t; - -typedef enum { - BTAV_A2DP_CODEC_BITS_PER_SAMPLE_NONE = 0x0, - BTAV_A2DP_CODEC_BITS_PER_SAMPLE_16 = 0x1 << 0, - BTAV_A2DP_CODEC_BITS_PER_SAMPLE_24 = 0x1 << 1, - BTAV_A2DP_CODEC_BITS_PER_SAMPLE_32 = 0x1 << 2 -} btav_a2dp_codec_bits_per_sample_t; - -typedef enum { - BTAV_A2DP_CODEC_CHANNEL_MODE_NONE = 0x0, - BTAV_A2DP_CODEC_CHANNEL_MODE_MONO = 0x1 << 0, - BTAV_A2DP_CODEC_CHANNEL_MODE_STEREO = 0x1 << 1 -} btav_a2dp_codec_channel_mode_t; - -/* - * Structure for representing codec capability or configuration. - * It is used for configuring A2DP codec preference, and for reporting back - * current configuration or codec capability. - * For codec capability, fields "sample_rate", "bits_per_sample" and - * "channel_mode" can contain bit-masks with all supported features. - */ -typedef struct { - btav_a2dp_codec_index_t codec_type; - btav_a2dp_codec_priority_t codec_priority; // Codec selection priority - // relative to other codecs: larger value - // means higher priority. If 0, reset to - // default. - btav_a2dp_codec_sample_rate_t sample_rate; - btav_a2dp_codec_bits_per_sample_t bits_per_sample; - btav_a2dp_codec_channel_mode_t channel_mode; - int64_t codec_specific_1; // Codec-specific value 1 - int64_t codec_specific_2; // Codec-specific value 2 - int64_t codec_specific_3; // Codec-specific value 3 - int64_t codec_specific_4; // Codec-specific value 4 -} btav_a2dp_codec_config_t; - -/** Callback for connection state change. - * state will have one of the values from btav_connection_state_t - */ -typedef void (* btav_connection_state_callback)(btav_connection_state_t state, - RawAddress *bd_addr); - -/** Callback for audiopath state change. - * state will have one of the values from btav_audio_state_t - */ -typedef void (* btav_audio_state_callback)(btav_audio_state_t state, - RawAddress *bd_addr); - -/** Callback for audio configuration change. - * Used only for the A2DP Source interface. - */ -typedef void (* btav_audio_source_config_callback)( - btav_a2dp_codec_config_t codec_config, - std::vector codecs_local_capabilities, - std::vector codecs_selectable_capabilities); - -/** Callback for audio configuration change. - * Used only for the A2DP Sink interface. - * sample_rate: sample rate in Hz - * channel_count: number of channels (1 for mono, 2 for stereo) - */ -typedef void (* btav_audio_sink_config_callback)(RawAddress *bd_addr, - uint32_t sample_rate, - uint8_t channel_count); - -/** BT-AV A2DP Source callback structure. */ -typedef struct { - /** set to sizeof(btav_source_callbacks_t) */ - size_t size; - btav_connection_state_callback connection_state_cb; - btav_audio_state_callback audio_state_cb; - btav_audio_source_config_callback audio_config_cb; -} btav_source_callbacks_t; - -/** BT-AV A2DP Sink callback structure. */ -typedef struct { - /** set to sizeof(btav_sink_callbacks_t) */ - size_t size; - btav_connection_state_callback connection_state_cb; - btav_audio_state_callback audio_state_cb; - btav_audio_sink_config_callback audio_config_cb; -} btav_sink_callbacks_t; - -/** - * NOTE: - * - * 1. AVRCP 1.0 shall be supported initially. AVRCP passthrough commands - * shall be handled internally via uinput - * - * 2. A2DP data path shall be handled via a socket pipe between the AudioFlinger - * android_audio_hw library and the Bluetooth stack. - * - */ - -/** Represents the standard BT-AV A2DP Source interface. - */ -typedef struct { - - /** set to sizeof(btav_source_interface_t) */ - size_t size; - /** - * Register the BtAv callbacks. - */ - bt_status_t (*init)(btav_source_callbacks_t* callbacks, - std::vector codec_priorities); - - /** connect to headset */ - bt_status_t (*connect)( RawAddress *bd_addr ); - - /** dis-connect from headset */ - bt_status_t (*disconnect)( RawAddress *bd_addr ); - - /** configure the codecs settings preferences */ - bt_status_t (*config_codec)(std::vector codec_preferences); - - /** Closes the interface. */ - void (*cleanup)( void ); - -} btav_source_interface_t; - -/** Represents the standard BT-AV A2DP Sink interface. - */ -typedef struct { - - /** set to sizeof(btav_sink_interface_t) */ - size_t size; - /** - * Register the BtAv callbacks - */ - bt_status_t (*init)( btav_sink_callbacks_t* callbacks ); - - /** connect to headset */ - bt_status_t (*connect)( RawAddress *bd_addr ); - - /** dis-connect from headset */ - bt_status_t (*disconnect)( RawAddress *bd_addr ); - - /** Closes the interface. */ - void (*cleanup)( void ); - - /** Sends Audio Focus State. */ - void (*set_audio_focus_state)( int focus_state ); - - /** Sets the audio track gain. */ - void (*set_audio_track_gain)( float gain ); -} btav_sink_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_AV_H */ diff --git a/include/hardware/bt_common_types.h b/include/hardware/bt_common_types.h deleted file mode 100644 index 1deae27a..00000000 --- a/include/hardware/bt_common_types.h +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 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. - */ - -/****************************************************************************** - * - * This file contains constants and definitions that can be used commonly between JNI and stack layer - * - ******************************************************************************/ -#ifndef ANDROID_INCLUDE_BT_COMMON_TYPES_H -#define ANDROID_INCLUDE_BT_COMMON_TYPES_H - -#include "bluetooth.h" - -#include - -typedef struct -{ - uint8_t client_if; - uint8_t filt_index; - uint8_t advertiser_state; - uint8_t advertiser_info_present; - uint8_t addr_type; - uint8_t tx_power; - int8_t rssi_value; - uint16_t time_stamp; - RawAddress bd_addr; - uint8_t adv_pkt_len; - uint8_t *p_adv_pkt_data; - uint8_t scan_rsp_len; - uint8_t *p_scan_rsp_data; -} btgatt_track_adv_info_t; - -typedef enum -{ - BTGATT_DB_PRIMARY_SERVICE, - BTGATT_DB_SECONDARY_SERVICE, - BTGATT_DB_INCLUDED_SERVICE, - BTGATT_DB_CHARACTERISTIC, - BTGATT_DB_DESCRIPTOR, -} bt_gatt_db_attribute_type_t; - -typedef struct -{ - uint16_t id; - bluetooth::Uuid uuid; - bt_gatt_db_attribute_type_t type; - uint16_t attribute_handle; - - /* - * If |type| is |BTGATT_DB_PRIMARY_SERVICE|, or - * |BTGATT_DB_SECONDARY_SERVICE|, this contains the start and end attribute - * handles. - */ - uint16_t start_handle; - uint16_t end_handle; - - /* - * If |type| is |BTGATT_DB_CHARACTERISTIC|, this contains the properties of - * the characteristic. - */ - uint8_t properties; - uint16_t permissions; -} btgatt_db_element_t; - -typedef struct -{ - uint16_t feat_seln; - uint16_t list_logic_type; - uint8_t filt_logic_type; - uint8_t rssi_high_thres; - uint8_t rssi_low_thres; - uint8_t dely_mode; - uint16_t found_timeout; - uint16_t lost_timeout; - uint8_t found_timeout_cnt; - uint16_t num_of_tracking_entries; -} btgatt_filt_param_setup_t; - - -#endif /* ANDROID_INCLUDE_BT_COMMON_TYPES_H */ diff --git a/include/hardware/bt_gatt.h b/include/hardware/bt_gatt.h deleted file mode 100644 index 393d1a57..00000000 --- a/include/hardware/bt_gatt.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2013 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_INCLUDE_BT_GATT_H -#define ANDROID_INCLUDE_BT_GATT_H - -#include -#include "ble_advertiser.h" -#include "ble_scanner.h" -#include "bt_gatt_client.h" -#include "bt_gatt_server.h" - -__BEGIN_DECLS - -/** BT-GATT callbacks */ -typedef struct { - /** Set to sizeof(btgatt_callbacks_t) */ - size_t size; - - /** GATT Client callbacks */ - const btgatt_client_callbacks_t* client; - - /** GATT Server callbacks */ - const btgatt_server_callbacks_t* server; - - /** LE scanner callbacks */ - const btgatt_scanner_callbacks_t* scanner; -} btgatt_callbacks_t; - -/** Represents the standard Bluetooth GATT interface. */ -typedef struct { - /** Set to sizeof(btgatt_interface_t) */ - size_t size; - - /** - * Initializes the interface and provides callback routines - */ - bt_status_t (*init)( const btgatt_callbacks_t* callbacks ); - - /** Closes the interface */ - void (*cleanup)( void ); - - /** Pointer to the GATT client interface methods.*/ - const btgatt_client_interface_t* client; - - /** Pointer to the GATT server interface methods.*/ - const btgatt_server_interface_t* server; - - /** Pointer to the LE scanner interface methods.*/ - BleScannerInterface* scanner; - - /** Pointer to the advertiser interface methods.*/ - BleAdvertiserInterface* advertiser; -} btgatt_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_H */ diff --git a/include/hardware/bt_gatt_client.h b/include/hardware/bt_gatt_client.h deleted file mode 100644 index 1ec97447..00000000 --- a/include/hardware/bt_gatt_client.h +++ /dev/null @@ -1,299 +0,0 @@ -/* - * Copyright (C) 2013 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_INCLUDE_BT_GATT_CLIENT_H -#define ANDROID_INCLUDE_BT_GATT_CLIENT_H - -#include -#include -#include "bt_gatt_types.h" -#include "bt_common_types.h" - -#include - -__BEGIN_DECLS - -/** - * Buffer sizes for maximum attribute length and maximum read/write - * operation buffer size. - */ -#define BTGATT_MAX_ATTR_LEN 600 - -/** Buffer type for unformatted reads/writes */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - uint16_t len; -} btgatt_unformatted_value_t; - -/** Parameters for GATT read operations */ -typedef struct -{ - uint16_t handle; - btgatt_unformatted_value_t value; - uint16_t value_type; - uint8_t status; -} btgatt_read_params_t; - -/** Parameters for GATT write operations */ -typedef struct -{ - btgatt_srvc_id_t srvc_id; - btgatt_gatt_id_t char_id; - btgatt_gatt_id_t descr_id; - uint8_t status; -} btgatt_write_params_t; - -/** Attribute change notification parameters */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - RawAddress bda; - uint16_t handle; - uint16_t len; - uint8_t is_notify; -} btgatt_notify_params_t; - -typedef struct -{ - RawAddress *bda1; - bluetooth::Uuid *uuid1; - uint16_t u1; - uint16_t u2; - uint16_t u3; - uint16_t u4; - uint16_t u5; -} btgatt_test_params_t; - -/* BT GATT client error codes */ -typedef enum -{ - BT_GATTC_COMMAND_SUCCESS = 0, /* 0 Command succeeded */ - BT_GATTC_COMMAND_STARTED, /* 1 Command started OK. */ - BT_GATTC_COMMAND_BUSY, /* 2 Device busy with another command */ - BT_GATTC_COMMAND_STORED, /* 3 request is stored in control block */ - BT_GATTC_NO_RESOURCES, /* 4 No resources to issue command */ - BT_GATTC_MODE_UNSUPPORTED, /* 5 Request for 1 or more unsupported modes */ - BT_GATTC_ILLEGAL_VALUE, /* 6 Illegal command /parameter value */ - BT_GATTC_INCORRECT_STATE, /* 7 Device in wrong state for request */ - BT_GATTC_UNKNOWN_ADDR, /* 8 Unknown remote BD address */ - BT_GATTC_DEVICE_TIMEOUT, /* 9 Device timeout */ - BT_GATTC_INVALID_CONTROLLER_OUTPUT,/* 10 An incorrect value was received from HCI */ - BT_GATTC_SECURITY_ERROR, /* 11 Authorization or security failure or not authorized */ - BT_GATTC_DELAYED_ENCRYPTION_CHECK, /*12 Delayed encryption check */ - BT_GATTC_ERR_PROCESSING /* 12 Generic error */ -} btgattc_error_t; - -/** BT-GATT Client callback structure. */ - -/** Callback invoked in response to register_client */ -typedef void (*register_client_callback)(int status, int client_if, const bluetooth::Uuid& app_uuid); - -/** GATT open callback invoked in response to open */ -typedef void (*connect_callback)(int conn_id, int status, int client_if, const RawAddress& bda); - -/** Callback invoked in response to close */ -typedef void (*disconnect_callback)(int conn_id, int status, - int client_if, const RawAddress& bda); - -/** - * Invoked in response to search_service when the GATT service search - * has been completed. - */ -typedef void (*search_complete_callback)(int conn_id, int status); - -/** Callback invoked in response to [de]register_for_notification */ -typedef void (*register_for_notification_callback)(int conn_id, - int registered, int status, uint16_t handle); - -/** - * Remote device notification callback, invoked when a remote device sends - * a notification or indication that a client has registered for. - */ -typedef void (*notify_callback)(int conn_id, const btgatt_notify_params_t& p_data); - -/** Reports result of a GATT read operation */ -typedef void (*read_characteristic_callback)(int conn_id, int status, - btgatt_read_params_t *p_data); - -/** GATT write characteristic operation callback */ -typedef void (*write_characteristic_callback)(int conn_id, int status, uint16_t handle); - -/** GATT execute prepared write callback */ -typedef void (*execute_write_callback)(int conn_id, int status); - -/** Callback invoked in response to read_descriptor */ -typedef void (*read_descriptor_callback)(int conn_id, int status, - const btgatt_read_params_t& p_data); - -/** Callback invoked in response to write_descriptor */ -typedef void (*write_descriptor_callback)(int conn_id, int status, uint16_t handle); - -/** Callback triggered in response to read_remote_rssi */ -typedef void (*read_remote_rssi_callback)(int client_if, const RawAddress& bda, - int rssi, int status); - -/** Callback invoked when the MTU for a given connection changes */ -typedef void (*configure_mtu_callback)(int conn_id, int status, int mtu); - - -/** - * Callback notifying an application that a remote device connection is currently congested - * and cannot receive any more data. An application should avoid sending more data until - * a further callback is received indicating the congestion status has been cleared. - */ -typedef void (*congestion_callback)(int conn_id, bool congested); - -/** GATT get database callback */ -typedef void (*get_gatt_db_callback)(int conn_id, const btgatt_db_element_t* db, int count); - -/** GATT services between start_handle and end_handle were removed */ -typedef void (*services_removed_callback)(int conn_id, uint16_t start_handle, uint16_t end_handle); - -/** GATT services were added */ -typedef void (*services_added_callback)(int conn_id, const btgatt_db_element_t& added, int added_count); - -/** Callback invoked when the PHY for a given connection changes */ -typedef void (*phy_updated_callback)(int conn_id, uint8_t tx_phy, - uint8_t rx_phy, uint8_t status); - -/** Callback invoked when the connection parameters for a given connection changes */ -typedef void (*conn_updated_callback)(int conn_id, uint16_t interval, - uint16_t latency, uint16_t timeout, - uint8_t status); - -typedef struct { - register_client_callback register_client_cb; - connect_callback open_cb; - disconnect_callback close_cb; - search_complete_callback search_complete_cb; - register_for_notification_callback register_for_notification_cb; - notify_callback notify_cb; - read_characteristic_callback read_characteristic_cb; - write_characteristic_callback write_characteristic_cb; - read_descriptor_callback read_descriptor_cb; - write_descriptor_callback write_descriptor_cb; - execute_write_callback execute_write_cb; - read_remote_rssi_callback read_remote_rssi_cb; - configure_mtu_callback configure_mtu_cb; - congestion_callback congestion_cb; - get_gatt_db_callback get_gatt_db_cb; - services_removed_callback services_removed_cb; - services_added_callback services_added_cb; - phy_updated_callback phy_updated_cb; - conn_updated_callback conn_updated_cb; -} btgatt_client_callbacks_t; - -/** Represents the standard BT-GATT client interface. */ - -typedef struct { - /** Registers a GATT client application with the stack */ - bt_status_t (*register_client)(const bluetooth::Uuid& uuid); - - /** Unregister a client application from the stack */ - bt_status_t (*unregister_client)(int client_if); - - /** Create a connection to a remote LE or dual-mode device */ - bt_status_t (*connect)(int client_if, const RawAddress& bd_addr, - bool is_direct, int transport, bool opportunistic, - int initiating_phys); - - /** Disconnect a remote device or cancel a pending connection */ - bt_status_t (*disconnect)( int client_if, const RawAddress& bd_addr, - int conn_id); - - /** Clear the attribute cache for a given device */ - bt_status_t (*refresh)( int client_if, const RawAddress& bd_addr); - - /** - * Enumerate all GATT services on a connected device. - * Optionally, the results can be filtered for a given UUID. - */ - bt_status_t (*search_service)(int conn_id, const bluetooth::Uuid *filter_uuid); - - /** - * Sead "Find service by UUID" request. Used only for PTS tests. - */ - void (*btif_gattc_discover_service_by_uuid)(int conn_id, const bluetooth::Uuid& uuid); - - /** Read a characteristic on a remote device */ - bt_status_t (*read_characteristic)(int conn_id, uint16_t handle, - int auth_req); - - /** Read a characteristic on a remote device */ - bt_status_t (*read_using_characteristic_uuid)( - int conn_id, const bluetooth::Uuid& uuid, uint16_t s_handle, - uint16_t e_handle, int auth_req); - - /** Write a remote characteristic */ - bt_status_t (*write_characteristic)(int conn_id, uint16_t handle, - int write_type, int auth_req, - std::vector value); - - /** Read the descriptor for a given characteristic */ - bt_status_t (*read_descriptor)(int conn_id, uint16_t handle, int auth_req); - - /** Write a remote descriptor for a given characteristic */ - bt_status_t (*write_descriptor)( int conn_id, uint16_t handle, - int auth_req, std::vector value); - - /** Execute a prepared write operation */ - bt_status_t (*execute_write)(int conn_id, int execute); - - /** - * Register to receive notifications or indications for a given - * characteristic - */ - bt_status_t (*register_for_notification)( int client_if, - const RawAddress& bd_addr, uint16_t handle); - - /** Deregister a previous request for notifications/indications */ - bt_status_t (*deregister_for_notification)( int client_if, - const RawAddress& bd_addr, uint16_t handle); - - /** Request RSSI for a given remote device */ - bt_status_t (*read_remote_rssi)(int client_if, const RawAddress& bd_addr); - - /** Determine the type of the remote device (LE, BR/EDR, Dual-mode) */ - int (*get_device_type)(const RawAddress &bd_addr); - - /** Configure the MTU for a given connection */ - bt_status_t (*configure_mtu)(int conn_id, int mtu); - - /** Request a connection parameter update */ - bt_status_t (*conn_parameter_update)(const RawAddress& bd_addr, int min_interval, - int max_interval, int latency, int timeout); - - bt_status_t (*set_preferred_phy)(const RawAddress& bd_addr, uint8_t tx_phy, - uint8_t rx_phy, uint16_t phy_options); - - bt_status_t (*read_phy)( - const RawAddress& bd_addr, - base::Callback - cb); - - /** Test mode interface */ - bt_status_t (*test_command)( int command, const btgatt_test_params_t& params); - - /** Get gatt db content */ - bt_status_t (*get_gatt_db)( int conn_id); - -} btgatt_client_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/include/hardware/bt_gatt_server.h b/include/hardware/bt_gatt_server.h deleted file mode 100644 index 0a9cb9f5..00000000 --- a/include/hardware/bt_gatt_server.h +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2013 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_INCLUDE_BT_GATT_SERVER_H -#define ANDROID_INCLUDE_BT_GATT_SERVER_H - -#include -#include - -#include "bt_gatt_types.h" - -__BEGIN_DECLS - -/** GATT value type used in response to remote read requests */ -typedef struct -{ - uint8_t value[BTGATT_MAX_ATTR_LEN]; - uint16_t handle; - uint16_t offset; - uint16_t len; - uint8_t auth_req; -} btgatt_value_t; - -/** GATT remote read request response type */ -typedef union -{ - btgatt_value_t attr_value; - uint16_t handle; -} btgatt_response_t; - -/** BT-GATT Server callback structure. */ - -/** Callback invoked in response to register_server */ -typedef void (*register_server_callback)(int status, int server_if, - const bluetooth::Uuid& app_uuid); - -/** Callback indicating that a remote device has connected or been disconnected */ -typedef void (*connection_callback)(int conn_id, int server_if, int connected, - const RawAddress& bda); - -/** Callback invoked in response to create_service */ -typedef void (*service_added_callback)(int status, int server_if, - std::vector service); - -/** Callback invoked in response to stop_service */ -typedef void (*service_stopped_callback)(int status, int server_if, - int srvc_handle); - -/** Callback triggered when a service has been deleted */ -typedef void (*service_deleted_callback)(int status, int server_if, - int srvc_handle); - -/** - * Callback invoked when a remote device has requested to read a characteristic - * or descriptor. The application must respond by calling send_response - */ -typedef void (*request_read_callback)(int conn_id, int trans_id, const RawAddress& bda, - int attr_handle, int offset, bool is_long); - -/** - * Callback invoked when a remote device has requested to write to a - * characteristic or descriptor. - */ -typedef void (*request_write_callback)(int conn_id, int trans_id, const RawAddress& bda, - int attr_handle, int offset, bool need_rsp, - bool is_prep, std::vector value); - -/** Callback invoked when a previously prepared write is to be executed */ -typedef void (*request_exec_write_callback)(int conn_id, int trans_id, - const RawAddress& bda, int exec_write); - -/** - * Callback triggered in response to send_response if the remote device - * sends a confirmation. - */ -typedef void (*response_confirmation_callback)(int status, int handle); - -/** - * Callback confirming that a notification or indication has been sent - * to a remote device. - */ -typedef void (*indication_sent_callback)(int conn_id, int status); - -/** - * Callback notifying an application that a remote device connection is currently congested - * and cannot receive any more data. An application should avoid sending more data until - * a further callback is received indicating the congestion status has been cleared. - */ -typedef void (*congestion_callback)(int conn_id, bool congested); - -/** Callback invoked when the MTU for a given connection changes */ -typedef void (*mtu_changed_callback)(int conn_id, int mtu); - -/** Callback invoked when the PHY for a given connection changes */ -typedef void (*phy_updated_callback)(int conn_id, uint8_t tx_phy, - uint8_t rx_phy, uint8_t status); - -/** Callback invoked when the connection parameters for a given connection changes */ -typedef void (*conn_updated_callback)(int conn_id, uint16_t interval, - uint16_t latency, uint16_t timeout, - uint8_t status); -typedef struct { - register_server_callback register_server_cb; - connection_callback connection_cb; - service_added_callback service_added_cb; - service_stopped_callback service_stopped_cb; - service_deleted_callback service_deleted_cb; - request_read_callback request_read_characteristic_cb; - request_read_callback request_read_descriptor_cb; - request_write_callback request_write_characteristic_cb; - request_write_callback request_write_descriptor_cb; - request_exec_write_callback request_exec_write_cb; - response_confirmation_callback response_confirmation_cb; - indication_sent_callback indication_sent_cb; - congestion_callback congestion_cb; - mtu_changed_callback mtu_changed_cb; - phy_updated_callback phy_updated_cb; - conn_updated_callback conn_updated_cb; -} btgatt_server_callbacks_t; - -/** Represents the standard BT-GATT server interface. */ -typedef struct { - /** Registers a GATT server application with the stack */ - bt_status_t (*register_server)(const bluetooth::Uuid& uuid); - - /** Unregister a server application from the stack */ - bt_status_t (*unregister_server)(int server_if ); - - /** Create a connection to a remote peripheral */ - bt_status_t (*connect)(int server_if, const RawAddress& bd_addr, - bool is_direct, int transport); - - /** Disconnect an established connection or cancel a pending one */ - bt_status_t (*disconnect)(int server_if, const RawAddress& bd_addr, - int conn_id ); - - /** Create a new service */ - bt_status_t (*add_service)(int server_if, std::vector service); - - /** Stops a local service */ - bt_status_t (*stop_service)(int server_if, int service_handle); - - /** Delete a local service */ - bt_status_t (*delete_service)(int server_if, int service_handle); - - /** Send value indication to a remote device */ - bt_status_t (*send_indication)(int server_if, int attribute_handle, - int conn_id, int confirm, - std::vector value); - - /** Send a response to a read/write operation */ - bt_status_t (*send_response)(int conn_id, int trans_id, - int status, const btgatt_response_t& response); - - bt_status_t (*set_preferred_phy)(const RawAddress& bd_addr, uint8_t tx_phy, - uint8_t rx_phy, uint16_t phy_options); - - bt_status_t (*read_phy)( - const RawAddress& bd_addr, - base::Callback - cb); - -} btgatt_server_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_CLIENT_H */ diff --git a/include/hardware/bt_gatt_types.h b/include/hardware/bt_gatt_types.h deleted file mode 100644 index 7130c171..00000000 --- a/include/hardware/bt_gatt_types.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2013 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_INCLUDE_BT_GATT_TYPES_H -#define ANDROID_INCLUDE_BT_GATT_TYPES_H - -#include -#include - -#include - -__BEGIN_DECLS - -/** - * GATT Service types - */ -#define BTGATT_SERVICE_TYPE_PRIMARY 0 -#define BTGATT_SERVICE_TYPE_SECONDARY 1 - -/** GATT ID adding instance id tracking to the UUID */ -typedef struct -{ - bluetooth::Uuid uuid; - uint8_t inst_id; -} btgatt_gatt_id_t; - -/** GATT Service ID also identifies the service type (primary/secondary) */ -typedef struct -{ - btgatt_gatt_id_t id; - uint8_t is_primary; -} btgatt_srvc_id_t; - -/** Preferred physical Transport for GATT connection */ -typedef enum -{ - GATT_TRANSPORT_AUTO, - GATT_TRANSPORT_BREDR, - GATT_TRANSPORT_LE -} btgatt_transport_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_GATT_TYPES_H */ diff --git a/include/hardware/bt_hd.h b/include/hardware/bt_hd.h deleted file mode 100644 index c99ab247..00000000 --- a/include/hardware/bt_hd.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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 ANDROID_INCLUDE_BT_HD_H -#define ANDROID_INCLUDE_BT_HD_H - -#include - -__BEGIN_DECLS - -typedef enum -{ - BTHD_REPORT_TYPE_OTHER = 0, - BTHD_REPORT_TYPE_INPUT, - BTHD_REPORT_TYPE_OUTPUT, - BTHD_REPORT_TYPE_FEATURE, - BTHD_REPORT_TYPE_INTRDATA // special value for reports to be sent on INTR (INPUT is assumed) -} bthd_report_type_t; - -typedef enum -{ - BTHD_APP_STATE_NOT_REGISTERED, - BTHD_APP_STATE_REGISTERED -} bthd_application_state_t; - -typedef enum -{ - BTHD_CONN_STATE_CONNECTED, - BTHD_CONN_STATE_CONNECTING, - BTHD_CONN_STATE_DISCONNECTED, - BTHD_CONN_STATE_DISCONNECTING, - BTHD_CONN_STATE_UNKNOWN -} bthd_connection_state_t; - -typedef struct -{ - const char *name; - const char *description; - const char *provider; - uint8_t subclass; - uint8_t *desc_list; - int desc_list_len; -} bthd_app_param_t; - -typedef struct -{ - uint8_t service_type; - uint32_t token_rate; - uint32_t token_bucket_size; - uint32_t peak_bandwidth; - uint32_t access_latency; - uint32_t delay_variation; -} bthd_qos_param_t; - -typedef void (* bthd_application_state_callback)(RawAddress *bd_addr, bthd_application_state_t state); -typedef void (* bthd_connection_state_callback)(RawAddress *bd_addr, bthd_connection_state_t state); -typedef void (* bthd_get_report_callback)(uint8_t type, uint8_t id, uint16_t buffer_size); -typedef void (* bthd_set_report_callback)(uint8_t type, uint8_t id, uint16_t len, uint8_t *p_data); -typedef void (* bthd_set_protocol_callback)(uint8_t protocol); -typedef void (* bthd_intr_data_callback)(uint8_t report_id, uint16_t len, uint8_t *p_data); -typedef void (* bthd_vc_unplug_callback)(void); - -/** BT-HD callbacks */ -typedef struct { - size_t size; - - bthd_application_state_callback application_state_cb; - bthd_connection_state_callback connection_state_cb; - bthd_get_report_callback get_report_cb; - bthd_set_report_callback set_report_cb; - bthd_set_protocol_callback set_protocol_cb; - bthd_intr_data_callback intr_data_cb; - bthd_vc_unplug_callback vc_unplug_cb; -} bthd_callbacks_t; - -/** BT-HD interface */ -typedef struct { - - size_t size; - - /** init interface and register callbacks */ - bt_status_t (*init)(bthd_callbacks_t* callbacks); - - /** close interface */ - void (*cleanup)(void); - - /** register application */ - bt_status_t (*register_app)(bthd_app_param_t *app_param, bthd_qos_param_t *in_qos, - bthd_qos_param_t *out_qos); - - /** unregister application */ - bt_status_t (*unregister_app)(void); - - /** connects to host with virtual cable */ - bt_status_t (*connect)(RawAddress *bd_addr); - - /** disconnects from currently connected host */ - bt_status_t (*disconnect)(void); - - /** send report */ - bt_status_t (*send_report)(bthd_report_type_t type, uint8_t id, uint16_t len, uint8_t *p_data); - - /** notifies error for invalid SET_REPORT */ - bt_status_t (*report_error)(uint8_t error); - - /** send Virtual Cable Unplug */ - bt_status_t (*virtual_cable_unplug)(void); - -} bthd_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HD_H */ - diff --git a/include/hardware/bt_hf.h b/include/hardware/bt_hf.h deleted file mode 100644 index 1f6f6ebe..00000000 --- a/include/hardware/bt_hf.h +++ /dev/null @@ -1,333 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_HF_H -#define ANDROID_INCLUDE_BT_HF_H - -__BEGIN_DECLS - -/* AT response code - OK/Error */ -typedef enum { - BTHF_AT_RESPONSE_ERROR = 0, - BTHF_AT_RESPONSE_OK -} bthf_at_response_t; - -typedef enum { - BTHF_CONNECTION_STATE_DISCONNECTED = 0, - BTHF_CONNECTION_STATE_CONNECTING, - BTHF_CONNECTION_STATE_CONNECTED, - BTHF_CONNECTION_STATE_SLC_CONNECTED, - BTHF_CONNECTION_STATE_DISCONNECTING -} bthf_connection_state_t; - -typedef enum { - BTHF_AUDIO_STATE_DISCONNECTED = 0, - BTHF_AUDIO_STATE_CONNECTING, - BTHF_AUDIO_STATE_CONNECTED, - BTHF_AUDIO_STATE_DISCONNECTING -} bthf_audio_state_t; - -typedef enum { - BTHF_VR_STATE_STOPPED = 0, - BTHF_VR_STATE_STARTED -} bthf_vr_state_t; - -typedef enum { - BTHF_VOLUME_TYPE_SPK = 0, - BTHF_VOLUME_TYPE_MIC -} bthf_volume_type_t; - -/* Noise Reduction and Echo Cancellation */ -typedef enum -{ - BTHF_NREC_STOP, - BTHF_NREC_START -} bthf_nrec_t; - -/* WBS codec setting */ -typedef enum -{ - BTHF_WBS_NONE, - BTHF_WBS_NO, - BTHF_WBS_YES -}bthf_wbs_config_t; - -/* CHLD - Call held handling */ -typedef enum -{ - BTHF_CHLD_TYPE_RELEASEHELD, // Terminate all held or set UDUB("busy") to a waiting call - BTHF_CHLD_TYPE_RELEASEACTIVE_ACCEPTHELD, // Terminate all active calls and accepts a waiting/held call - BTHF_CHLD_TYPE_HOLDACTIVE_ACCEPTHELD, // Hold all active calls and accepts a waiting/held call - 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 - */ -typedef void (* bthf_connection_state_callback)(bthf_connection_state_t state, RawAddress *bd_addr); - -/** Callback for audio connection state change. - * state will have one of the values from BtHfAudioState - */ -typedef void (* bthf_audio_state_callback)(bthf_audio_state_t state, RawAddress *bd_addr); - -/** Callback for VR connection state change. - * state will have one of the values from BtHfVRState - */ -typedef void (* bthf_vr_cmd_callback)(bthf_vr_state_t state, RawAddress *bd_addr); - -/** Callback for answer incoming call (ATA) - */ -typedef void (* bthf_answer_call_cmd_callback)(RawAddress *bd_addr); - -/** Callback for disconnect call (AT+CHUP) - */ -typedef void (* bthf_hangup_call_cmd_callback)(RawAddress *bd_addr); - -/** Callback for disconnect call (AT+CHUP) - * type will denote Speaker/Mic gain (BtHfVolumeControl). - */ -typedef void (* bthf_volume_cmd_callback)(bthf_volume_type_t type, int volume, RawAddress *bd_addr); - -/** Callback for dialing an outgoing call - * If number is NULL, redial - */ -typedef void (* bthf_dial_call_cmd_callback)(char *number, RawAddress *bd_addr); - -/** Callback for sending DTMF tones - * tone contains the dtmf character to be sent - */ -typedef void (* bthf_dtmf_cmd_callback)(char tone, RawAddress *bd_addr); - -/** Callback for enabling/disabling noise reduction/echo cancellation - * value will be 1 to enable, 0 to disable - */ -typedef void (* bthf_nrec_cmd_callback)(bthf_nrec_t nrec, RawAddress *bd_addr); - -/** Callback for AT+BCS and event from BAC - * WBS enable, WBS disable - */ -typedef void (* bthf_wbs_callback)(bthf_wbs_config_t wbs, RawAddress *bd_addr); - -/** Callback for call hold handling (AT+CHLD) - * value will contain the call hold command (0, 1, 2, 3) - */ -typedef void (* bthf_chld_cmd_callback)(bthf_chld_type_t chld, RawAddress *bd_addr); - -/** Callback for CNUM (subscriber number) - */ -typedef void (* bthf_cnum_cmd_callback)(RawAddress *bd_addr); - -/** Callback for indicators (CIND) - */ -typedef void (* bthf_cind_cmd_callback)(RawAddress *bd_addr); - -/** Callback for operator selection (COPS) - */ -typedef void (* bthf_cops_cmd_callback)(RawAddress *bd_addr); - -/** Callback for call list (AT+CLCC) - */ -typedef void (* bthf_clcc_cmd_callback) (RawAddress *bd_addr); - -/** Callback for unknown AT command recd from HF - * at_string will contain the unparsed AT string - */ -typedef void (* bthf_unknown_at_cmd_callback)(char *at_string, RawAddress *bd_addr); - -/** Callback for keypressed (HSP) event. - */ -typedef void (* bthf_key_pressed_cmd_callback)(RawAddress *bd_addr); - -/** Callback for BIND. Pass the remote HF Indicators supported. - */ -typedef void (* bthf_bind_cmd_callback)(char *at_string, RawAddress *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, - RawAddress *bd_addr); - -/** BT-HF callback structure. */ -typedef struct { - /** set to sizeof(BtHfCallbacks) */ - size_t size; - bthf_connection_state_callback connection_state_cb; - bthf_audio_state_callback audio_state_cb; - bthf_vr_cmd_callback vr_cmd_cb; - bthf_answer_call_cmd_callback answer_call_cmd_cb; - bthf_hangup_call_cmd_callback hangup_call_cmd_cb; - bthf_volume_cmd_callback volume_cmd_cb; - bthf_dial_call_cmd_callback dial_call_cmd_cb; - bthf_dtmf_cmd_callback dtmf_cmd_cb; - bthf_nrec_cmd_callback nrec_cmd_cb; - bthf_wbs_callback wbs_cb; - bthf_chld_cmd_callback chld_cmd_cb; - bthf_cnum_cmd_callback cnum_cmd_cb; - bthf_cind_cmd_callback cind_cmd_cb; - 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; - -/** Network Status */ -typedef enum -{ - BTHF_NETWORK_STATE_NOT_AVAILABLE = 0, - BTHF_NETWORK_STATE_AVAILABLE -} bthf_network_state_t; - -/** Service type */ -typedef enum -{ - BTHF_SERVICE_TYPE_HOME = 0, - BTHF_SERVICE_TYPE_ROAMING -} bthf_service_type_t; - -typedef enum { - BTHF_CALL_STATE_ACTIVE = 0, - BTHF_CALL_STATE_HELD, - BTHF_CALL_STATE_DIALING, - BTHF_CALL_STATE_ALERTING, - BTHF_CALL_STATE_INCOMING, - BTHF_CALL_STATE_WAITING, - BTHF_CALL_STATE_IDLE -} bthf_call_state_t; - -typedef enum { - BTHF_CALL_DIRECTION_OUTGOING = 0, - BTHF_CALL_DIRECTION_INCOMING -} bthf_call_direction_t; - -typedef enum { - BTHF_CALL_TYPE_VOICE = 0, - BTHF_CALL_TYPE_DATA, - BTHF_CALL_TYPE_FAX -} bthf_call_mode_t; - -typedef enum { - BTHF_CALL_MPTY_TYPE_SINGLE = 0, - BTHF_CALL_MPTY_TYPE_MULTI -} bthf_call_mpty_type_t; - -typedef enum { - BTHF_CALL_ADDRTYPE_UNKNOWN = 0x81, - BTHF_CALL_ADDRTYPE_INTERNATIONAL = 0x91 -} bthf_call_addrtype_t; -/** Represents the standard BT-HF interface. */ -typedef struct { - - /** set to sizeof(BtHfInterface) */ - size_t size; - /** - * Register the BtHf callbacks - */ - bt_status_t (*init)( bthf_callbacks_t* callbacks, int max_hf_clients, bool inband_ringing_supported); - - /** connect to headset */ - bt_status_t (*connect)( RawAddress *bd_addr ); - - /** dis-connect from headset */ - bt_status_t (*disconnect)( RawAddress *bd_addr ); - - /** create an audio connection */ - bt_status_t (*connect_audio)( RawAddress *bd_addr ); - - /** close the audio connection */ - bt_status_t (*disconnect_audio)( RawAddress *bd_addr ); - - /** start voice recognition */ - bt_status_t (*start_voice_recognition)( RawAddress *bd_addr ); - - /** stop voice recognition */ - bt_status_t (*stop_voice_recognition)( RawAddress *bd_addr ); - - /** volume control */ - bt_status_t (*volume_control) (bthf_volume_type_t type, int volume, RawAddress *bd_addr ); - - /** Combined device status change notification */ - bt_status_t (*device_status_notification)(bthf_network_state_t ntk_state, bthf_service_type_t svc_type, int signal, - int batt_chg); - - /** Response for COPS command */ - bt_status_t (*cops_response)(const char *cops, RawAddress *bd_addr ); - - /** Response for CIND command */ - bt_status_t (*cind_response)(int svc, int num_active, int num_held, bthf_call_state_t call_setup_state, - int signal, int roam, int batt_chg, RawAddress *bd_addr ); - - /** Pre-formatted AT response, typically in response to unknown AT cmd */ - bt_status_t (*formatted_at_response)(const char *rsp, RawAddress *bd_addr ); - - /** ok/error response - * ERROR (0) - * OK (1) - */ - bt_status_t (*at_response) (bthf_at_response_t response_code, int error_code, RawAddress *bd_addr ); - - /** response for CLCC command - * Can be iteratively called for each call index - * Call index of 0 will be treated as NULL termination (Completes response) - */ - bt_status_t (*clcc_response) (int index, bthf_call_direction_t dir, - bthf_call_state_t state, bthf_call_mode_t mode, - bthf_call_mpty_type_t mpty, const char *number, - bthf_call_addrtype_t type, RawAddress *bd_addr ); - - /** notify of a call state change - * Each update notifies - * 1. Number of active/held/ringing calls - * 2. call_state: This denotes the state change that triggered this msg - * This will take one of the values from BtHfCallState - * 3. number & type: valid only for incoming & waiting call - */ - bt_status_t (*phone_state_change) (int num_active, int num_held, bthf_call_state_t call_setup_state, - const char *number, bthf_call_addrtype_t type); - - /** Closes the interface. */ - void (*cleanup)( void ); - - /** configuration for the SCO codec */ - bt_status_t (*configure_wbs)( RawAddress *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, - RawAddress *bd_addr); - - /** Whether we will initiate SCO or not **/ - bt_status_t (*set_sco_allowed)(bool value); -} bthf_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HF_H */ diff --git a/include/hardware/bt_hf_client.h b/include/hardware/bt_hf_client.h deleted file mode 100644 index 52072964..00000000 --- a/include/hardware/bt_hf_client.h +++ /dev/null @@ -1,383 +0,0 @@ -/* - * Copyright (C) 2012-2014 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_INCLUDE_BT_HF_CLIENT_H -#define ANDROID_INCLUDE_BT_HF_CLIENT_H - -__BEGIN_DECLS - -typedef enum { - BTHF_CLIENT_CONNECTION_STATE_DISCONNECTED = 0, - BTHF_CLIENT_CONNECTION_STATE_CONNECTING, - BTHF_CLIENT_CONNECTION_STATE_CONNECTED, - BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED, - BTHF_CLIENT_CONNECTION_STATE_DISCONNECTING -} bthf_client_connection_state_t; - -typedef enum { - BTHF_CLIENT_AUDIO_STATE_DISCONNECTED = 0, - BTHF_CLIENT_AUDIO_STATE_CONNECTING, - BTHF_CLIENT_AUDIO_STATE_CONNECTED, - BTHF_CLIENT_AUDIO_STATE_CONNECTED_MSBC, -} bthf_client_audio_state_t; - -typedef enum { - BTHF_CLIENT_VR_STATE_STOPPED = 0, - BTHF_CLIENT_VR_STATE_STARTED -} bthf_client_vr_state_t; - -typedef enum { - BTHF_CLIENT_VOLUME_TYPE_SPK = 0, - BTHF_CLIENT_VOLUME_TYPE_MIC -} bthf_client_volume_type_t; - -typedef enum -{ - BTHF_CLIENT_NETWORK_STATE_NOT_AVAILABLE = 0, - BTHF_CLIENT_NETWORK_STATE_AVAILABLE -} bthf_client_network_state_t; - -typedef enum -{ - BTHF_CLIENT_SERVICE_TYPE_HOME = 0, - BTHF_CLIENT_SERVICE_TYPE_ROAMING -} bthf_client_service_type_t; - -typedef enum { - BTHF_CLIENT_CALL_STATE_ACTIVE = 0, - BTHF_CLIENT_CALL_STATE_HELD, - BTHF_CLIENT_CALL_STATE_DIALING, - BTHF_CLIENT_CALL_STATE_ALERTING, - BTHF_CLIENT_CALL_STATE_INCOMING, - BTHF_CLIENT_CALL_STATE_WAITING, - BTHF_CLIENT_CALL_STATE_HELD_BY_RESP_HOLD, -} bthf_client_call_state_t; - -typedef enum { - BTHF_CLIENT_CALL_NO_CALLS_IN_PROGRESS = 0, - BTHF_CLIENT_CALL_CALLS_IN_PROGRESS -} bthf_client_call_t; - -typedef enum { - BTHF_CLIENT_CALLSETUP_NONE = 0, - BTHF_CLIENT_CALLSETUP_INCOMING, - BTHF_CLIENT_CALLSETUP_OUTGOING, - BTHF_CLIENT_CALLSETUP_ALERTING - -} bthf_client_callsetup_t; - -typedef enum { - BTHF_CLIENT_CALLHELD_NONE = 0, - BTHF_CLIENT_CALLHELD_HOLD_AND_ACTIVE, - BTHF_CLIENT_CALLHELD_HOLD, -} bthf_client_callheld_t; - -typedef enum { - BTHF_CLIENT_RESP_AND_HOLD_HELD = 0, - BTRH_CLIENT_RESP_AND_HOLD_ACCEPT, - BTRH_CLIENT_RESP_AND_HOLD_REJECT, -} bthf_client_resp_and_hold_t; - -typedef enum { - BTHF_CLIENT_CALL_DIRECTION_OUTGOING = 0, - BTHF_CLIENT_CALL_DIRECTION_INCOMING -} bthf_client_call_direction_t; - -typedef enum { - BTHF_CLIENT_CALL_MPTY_TYPE_SINGLE = 0, - BTHF_CLIENT_CALL_MPTY_TYPE_MULTI -} bthf_client_call_mpty_type_t; - -typedef enum { - BTHF_CLIENT_CMD_COMPLETE_OK = 0, - BTHF_CLIENT_CMD_COMPLETE_ERROR, - BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_CARRIER, - BTHF_CLIENT_CMD_COMPLETE_ERROR_BUSY, - BTHF_CLIENT_CMD_COMPLETE_ERROR_NO_ANSWER, - BTHF_CLIENT_CMD_COMPLETE_ERROR_DELAYED, - BTHF_CLIENT_CMD_COMPLETE_ERROR_BLACKLISTED, - BTHF_CLIENT_CMD_COMPLETE_ERROR_CME -} bthf_client_cmd_complete_t; - -typedef enum { - BTHF_CLIENT_CALL_ACTION_CHLD_0 = 0, - BTHF_CLIENT_CALL_ACTION_CHLD_1, - BTHF_CLIENT_CALL_ACTION_CHLD_2, - BTHF_CLIENT_CALL_ACTION_CHLD_3, - BTHF_CLIENT_CALL_ACTION_CHLD_4, - BTHF_CLIENT_CALL_ACTION_CHLD_1x, - BTHF_CLIENT_CALL_ACTION_CHLD_2x, - BTHF_CLIENT_CALL_ACTION_ATA, - BTHF_CLIENT_CALL_ACTION_CHUP, - BTHF_CLIENT_CALL_ACTION_BTRH_0, - BTHF_CLIENT_CALL_ACTION_BTRH_1, - BTHF_CLIENT_CALL_ACTION_BTRH_2, -} bthf_client_call_action_t; - -typedef enum { - BTHF_CLIENT_SERVICE_UNKNOWN = 0, - BTHF_CLIENT_SERVICE_VOICE, - BTHF_CLIENT_SERVICE_FAX -} bthf_client_subscriber_service_type_t; - -typedef enum { - BTHF_CLIENT_IN_BAND_RINGTONE_NOT_PROVIDED = 0, - BTHF_CLIENT_IN_BAND_RINGTONE_PROVIDED, -} bthf_client_in_band_ring_state_t; - -/* Peer features masks */ -#define BTHF_CLIENT_PEER_FEAT_3WAY 0x00000001 /* Three-way calling */ -#define BTHF_CLIENT_PEER_FEAT_ECNR 0x00000002 /* Echo cancellation and/or noise reduction */ -#define BTHF_CLIENT_PEER_FEAT_VREC 0x00000004 /* Voice recognition */ -#define BTHF_CLIENT_PEER_FEAT_INBAND 0x00000008 /* In-band ring tone */ -#define BTHF_CLIENT_PEER_FEAT_VTAG 0x00000010 /* Attach a phone number to a voice tag */ -#define BTHF_CLIENT_PEER_FEAT_REJECT 0x00000020 /* Ability to reject incoming call */ -#define BTHF_CLIENT_PEER_FEAT_ECS 0x00000040 /* Enhanced Call Status */ -#define BTHF_CLIENT_PEER_FEAT_ECC 0x00000080 /* Enhanced Call Control */ -#define BTHF_CLIENT_PEER_FEAT_EXTERR 0x00000100 /* Extended error codes */ -#define BTHF_CLIENT_PEER_FEAT_CODEC 0x00000200 /* Codec Negotiation */ - -/* Peer call handling features masks */ -#define BTHF_CLIENT_CHLD_FEAT_REL 0x00000001 /* 0 Release waiting call or held calls */ -#define BTHF_CLIENT_CHLD_FEAT_REL_ACC 0x00000002 /* 1 Release active calls and accept other - (waiting or held) cal */ -#define BTHF_CLIENT_CHLD_FEAT_REL_X 0x00000004 /* 1x Release specified active call only */ -#define BTHF_CLIENT_CHLD_FEAT_HOLD_ACC 0x00000008 /* 2 Active calls on hold and accept other - (waiting or held) call */ -#define BTHF_CLIENT_CHLD_FEAT_PRIV_X 0x00000010 /* 2x Request private mode with specified - call (put the rest on hold) */ -#define BTHF_CLIENT_CHLD_FEAT_MERGE 0x00000020 /* 3 Add held call to multiparty */ -#define BTHF_CLIENT_CHLD_FEAT_MERGE_DETACH 0x00000040 /* 4 Connect two calls and leave - (disconnect from) multiparty */ - -/** Callback for connection state change. - * state will have one of the values from BtHfConnectionState - * peer/chld_features are valid only for BTHF_CLIENT_CONNECTION_STATE_SLC_CONNECTED state - */ -typedef void (* bthf_client_connection_state_callback)(const RawAddress *bd_addr, - bthf_client_connection_state_t state, - unsigned int peer_feat, - unsigned int chld_feat); - -/** Callback for audio connection state change. - * state will have one of the values from BtHfAudioState - */ -typedef void (* bthf_client_audio_state_callback)(const RawAddress *bd_addr, - bthf_client_audio_state_t state); - -/** Callback for VR connection state change. - * state will have one of the values from BtHfVRState - */ -typedef void (* bthf_client_vr_cmd_callback)(const RawAddress *bd_addr, bthf_client_vr_state_t state); - -/** Callback for network state change - */ -typedef void (* bthf_client_network_state_callback) (const RawAddress *bd_addr, - bthf_client_network_state_t state); - -/** Callback for network roaming status change - */ -typedef void (* bthf_client_network_roaming_callback) (const RawAddress *bd_addr, - bthf_client_service_type_t type); - -/** Callback for signal strength indication - */ -typedef void (* bthf_client_network_signal_callback) (const RawAddress *bd_addr, - int signal_strength); - -/** Callback for battery level indication - */ -typedef void (* bthf_client_battery_level_callback) (const RawAddress *bd_addr, - int battery_level); - -/** Callback for current operator name - */ -typedef void (* bthf_client_current_operator_callback) (const RawAddress *bd_addr, - const char *name); - -/** Callback for call indicator - */ -typedef void (* bthf_client_call_callback) (const RawAddress *bd_addr, bthf_client_call_t call); - -/** Callback for callsetup indicator - */ -typedef void (* bthf_client_callsetup_callback) (const RawAddress *bd_addr, - bthf_client_callsetup_t callsetup); - -/** Callback for callheld indicator - */ -typedef void (* bthf_client_callheld_callback) (const RawAddress *bd_addr, - bthf_client_callheld_t callheld); - -/** Callback for response and hold - */ -typedef void (* bthf_client_resp_and_hold_callback) (const RawAddress *bd_addr, - bthf_client_resp_and_hold_t resp_and_hold); - -/** Callback for Calling Line Identification notification - * Will be called only when there is an incoming call and number is provided. - */ -typedef void (* bthf_client_clip_callback) (const RawAddress *bd_addr, const char *number); - -/** - * Callback for Call Waiting notification - */ -typedef void (* bthf_client_call_waiting_callback) (const RawAddress *bd_addr, const char *number); - -/** - * Callback for listing current calls. Can be called multiple time. - * If number is unknown NULL is passed. - */ -typedef void (*bthf_client_current_calls) (const RawAddress *bd_addr, int index, - bthf_client_call_direction_t dir, - bthf_client_call_state_t state, - bthf_client_call_mpty_type_t mpty, - const char *number); - -/** Callback for audio volume change - */ -typedef void (*bthf_client_volume_change_callback) (const RawAddress *bd_addr, - bthf_client_volume_type_t type, - int volume); - -/** Callback for command complete event - * cme is valid only for BTHF_CLIENT_CMD_COMPLETE_ERROR_CME type - */ -typedef void (*bthf_client_cmd_complete_callback) (const RawAddress *bd_addr, - bthf_client_cmd_complete_t type, - int cme); - -/** Callback for subscriber information - */ -typedef void (* bthf_client_subscriber_info_callback) (const RawAddress *bd_addr, - const char *name, - bthf_client_subscriber_service_type_t type); - -/** Callback for in-band ring tone settings - */ -typedef void (* bthf_client_in_band_ring_tone_callback) (const RawAddress *bd_addr, - bthf_client_in_band_ring_state_t state); - -/** - * Callback for requested number from AG - */ -typedef void (* bthf_client_last_voice_tag_number_callback) (const RawAddress *bd_addr, - const char *number); - -/** - * Callback for sending ring indication to app - */ -typedef void (* bthf_client_ring_indication_callback) (const RawAddress *bd_addr); - -/** BT-HF callback structure. */ -typedef struct { - /** set to sizeof(BtHfClientCallbacks) */ - size_t size; - bthf_client_connection_state_callback connection_state_cb; - bthf_client_audio_state_callback audio_state_cb; - bthf_client_vr_cmd_callback vr_cmd_cb; - bthf_client_network_state_callback network_state_cb; - bthf_client_network_roaming_callback network_roaming_cb; - bthf_client_network_signal_callback network_signal_cb; - bthf_client_battery_level_callback battery_level_cb; - bthf_client_current_operator_callback current_operator_cb; - bthf_client_call_callback call_cb; - bthf_client_callsetup_callback callsetup_cb; - bthf_client_callheld_callback callheld_cb; - bthf_client_resp_and_hold_callback resp_and_hold_cb; - bthf_client_clip_callback clip_cb; - bthf_client_call_waiting_callback call_waiting_cb; - bthf_client_current_calls current_calls_cb; - bthf_client_volume_change_callback volume_change_cb; - bthf_client_cmd_complete_callback cmd_complete_cb; - bthf_client_subscriber_info_callback subscriber_info_cb; - bthf_client_in_band_ring_tone_callback in_band_ring_tone_cb; - bthf_client_last_voice_tag_number_callback last_voice_tag_number_callback; - bthf_client_ring_indication_callback ring_indication_cb; -} bthf_client_callbacks_t; - -/** Represents the standard BT-HF interface. */ -typedef struct { - - /** set to sizeof(BtHfClientInterface) */ - size_t size; - /** - * Register the BtHf callbacks - */ - bt_status_t (*init)(bthf_client_callbacks_t* callbacks); - - /** connect to audio gateway */ - bt_status_t (*connect)(RawAddress *bd_addr); - - /** disconnect from audio gateway */ - bt_status_t (*disconnect)(const RawAddress *bd_addr); - - /** create an audio connection */ - bt_status_t (*connect_audio)(const RawAddress *bd_addr); - - /** close the audio connection */ - bt_status_t (*disconnect_audio)(const RawAddress *bd_addr); - - /** start voice recognition */ - bt_status_t (*start_voice_recognition)(const RawAddress *bd_addr); - - /** stop voice recognition */ - bt_status_t (*stop_voice_recognition)(const RawAddress *bd_addr); - - /** volume control */ - bt_status_t (*volume_control) (const RawAddress *bd_addr, - bthf_client_volume_type_t type, - int volume); - - /** place a call with number a number - * if number is NULL last called number is called (aka re-dial)*/ - bt_status_t (*dial) (const RawAddress *bd_addr, const char *number); - - /** place a call with number specified by location (speed dial) */ - bt_status_t (*dial_memory) (const RawAddress *bd_addr, int location); - - /** perform specified call related action - * idx is limited only for enhanced call control related action - */ - bt_status_t (*handle_call_action) (const RawAddress *bd_addr, - bthf_client_call_action_t action, - int idx); - - /** query list of current calls */ - bt_status_t (*query_current_calls) (const RawAddress *bd_addr); - - /** query name of current selected operator */ - bt_status_t (*query_current_operator_name) (const RawAddress *bd_addr); - - /** Retrieve subscriber information */ - bt_status_t (*retrieve_subscriber_info) (const RawAddress *bd_addr); - - /** Send DTMF code*/ - bt_status_t (*send_dtmf) (const RawAddress *bd_addr, char code); - - /** Request a phone number from AG corresponding to last voice tag recorded */ - bt_status_t (*request_last_voice_tag_number) (const RawAddress *bd_addr); - - /** Closes the interface. */ - void (*cleanup)(void); - - /** Send AT Command. */ - bt_status_t (*send_at_cmd) (const RawAddress *bd_addr, int cmd, int val1, int val2, const char *arg); -} bthf_client_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HF_CLIENT_H */ diff --git a/include/hardware/bt_hh.h b/include/hardware/bt_hh.h deleted file mode 100644 index c39e3e5b..00000000 --- a/include/hardware/bt_hh.h +++ /dev/null @@ -1,191 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_HH_H -#define ANDROID_INCLUDE_BT_HH_H - -#include - -__BEGIN_DECLS - -#define BTHH_MAX_DSC_LEN 884 - -/* HH connection states */ -typedef enum -{ - BTHH_CONN_STATE_CONNECTED = 0, - BTHH_CONN_STATE_CONNECTING, - BTHH_CONN_STATE_DISCONNECTED, - BTHH_CONN_STATE_DISCONNECTING, - BTHH_CONN_STATE_FAILED_MOUSE_FROM_HOST, - BTHH_CONN_STATE_FAILED_KBD_FROM_HOST, - BTHH_CONN_STATE_FAILED_TOO_MANY_DEVICES, - BTHH_CONN_STATE_FAILED_NO_BTHID_DRIVER, - BTHH_CONN_STATE_FAILED_GENERIC, - BTHH_CONN_STATE_UNKNOWN -} bthh_connection_state_t; - -typedef enum -{ - BTHH_OK = 0, - BTHH_HS_HID_NOT_READY, /* handshake error : device not ready */ - BTHH_HS_INVALID_RPT_ID, /* handshake error : invalid report ID */ - BTHH_HS_TRANS_NOT_SPT, /* handshake error : transaction not spt */ - BTHH_HS_INVALID_PARAM, /* handshake error : invalid paremter */ - BTHH_HS_ERROR, /* handshake error : unspecified HS error */ - BTHH_ERR, /* general BTA HH error */ - BTHH_ERR_SDP, /* SDP error */ - BTHH_ERR_PROTO, /* SET_Protocol error, - only used in BTA_HH_OPEN_EVT callback */ - BTHH_ERR_DB_FULL, /* device database full error, used */ - BTHH_ERR_TOD_UNSPT, /* type of device not supported */ - BTHH_ERR_NO_RES, /* out of system resources */ - BTHH_ERR_AUTH_FAILED, /* authentication fail */ - BTHH_ERR_HDL -}bthh_status_t; - -/* Protocol modes */ -typedef enum { - BTHH_REPORT_MODE = 0x00, - BTHH_BOOT_MODE = 0x01, - BTHH_UNSUPPORTED_MODE = 0xff -}bthh_protocol_mode_t; - -/* Report types */ -typedef enum { - BTHH_INPUT_REPORT = 1, - BTHH_OUTPUT_REPORT, - BTHH_FEATURE_REPORT -}bthh_report_type_t; - -typedef struct -{ - int attr_mask; - uint8_t sub_class; - uint8_t app_id; - int vendor_id; - int product_id; - int version; - uint8_t ctry_code; - int dl_len; - uint8_t dsc_list[BTHH_MAX_DSC_LEN]; -} bthh_hid_info_t; - -/** Callback for connection state change. - * state will have one of the values from bthh_connection_state_t - */ -typedef void (* bthh_connection_state_callback)(RawAddress *bd_addr, bthh_connection_state_t state); - -/** Callback for vitual unplug api. - * the status of the vitual unplug - */ -typedef void (* bthh_virtual_unplug_callback)(RawAddress *bd_addr, bthh_status_t hh_status); - -/** Callback for get hid info - * hid_info will contain attr_mask, sub_class, app_id, vendor_id, product_id, version, ctry_code, len - */ -typedef void (* bthh_hid_info_callback)(RawAddress *bd_addr, bthh_hid_info_t hid_info); - -/** Callback for get protocol api. - * the protocol mode is one of the value from bthh_protocol_mode_t - */ -typedef void (* bthh_protocol_mode_callback)(RawAddress *bd_addr, bthh_status_t hh_status, bthh_protocol_mode_t mode); - -/** Callback for get/set_idle_time api. - */ -typedef void (* bthh_idle_time_callback)(RawAddress *bd_addr, bthh_status_t hh_status, int idle_rate); - - -/** Callback for get report api. - * if staus is ok rpt_data contains the report data - */ -typedef void (* bthh_get_report_callback)(RawAddress *bd_addr, bthh_status_t hh_status, uint8_t* rpt_data, int rpt_size); - -/** Callback for set_report/set_protocol api and if error - * occurs for get_report/get_protocol api. - */ -typedef void (* bthh_handshake_callback)(RawAddress *bd_addr, bthh_status_t hh_status); - - -/** BT-HH callback structure. */ -typedef struct { - /** set to sizeof(BtHfCallbacks) */ - size_t size; - bthh_connection_state_callback connection_state_cb; - bthh_hid_info_callback hid_info_cb; - bthh_protocol_mode_callback protocol_mode_cb; - bthh_idle_time_callback idle_time_cb; - bthh_get_report_callback get_report_cb; - bthh_virtual_unplug_callback virtual_unplug_cb; - bthh_handshake_callback handshake_cb; - -} bthh_callbacks_t; - - - -/** Represents the standard BT-HH interface. */ -typedef struct { - - /** set to sizeof(BtHhInterface) */ - size_t size; - - /** - * Register the BtHh callbacks - */ - bt_status_t (*init)( bthh_callbacks_t* callbacks ); - - /** connect to hid device */ - bt_status_t (*connect)( RawAddress *bd_addr); - - /** dis-connect from hid device */ - bt_status_t (*disconnect)( RawAddress *bd_addr ); - - /** Virtual UnPlug (VUP) the specified HID device */ - bt_status_t (*virtual_unplug)(RawAddress *bd_addr); - - /** Set the HID device descriptor for the specified HID device. */ - bt_status_t (*set_info)(RawAddress *bd_addr, bthh_hid_info_t hid_info ); - - /** Get the HID proto mode. */ - bt_status_t (*get_protocol) (RawAddress *bd_addr, bthh_protocol_mode_t protocolMode); - - /** Set the HID proto mode. */ - bt_status_t (*set_protocol)(RawAddress *bd_addr, bthh_protocol_mode_t protocolMode); - - /** Get the HID Idle Time */ - bt_status_t (*get_idle_time)(RawAddress *bd_addr); - - /** Set the HID Idle Time */ - bt_status_t (*set_idle_time)(RawAddress *bd_addr, uint8_t idleTime); - - /** Send a GET_REPORT to HID device. */ - bt_status_t (*get_report)(RawAddress *bd_addr, bthh_report_type_t reportType, uint8_t reportId, int bufferSize); - - /** Send a SET_REPORT to HID device. */ - bt_status_t (*set_report)(RawAddress *bd_addr, bthh_report_type_t reportType, char* report); - - /** Send data to HID device. */ - bt_status_t (*send_data)(RawAddress *bd_addr, char* data); - - /** Closes the interface. */ - void (*cleanup)( void ); - -} bthh_interface_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HH_H */ - - diff --git a/include/hardware/bt_hl.h b/include/hardware/bt_hl.h deleted file mode 100644 index 6d909fbb..00000000 --- a/include/hardware/bt_hl.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_HL_H -#define ANDROID_INCLUDE_BT_HL_H - -__BEGIN_DECLS - -/* HL connection states */ - -typedef enum -{ - BTHL_MDEP_ROLE_SOURCE, - BTHL_MDEP_ROLE_SINK -} bthl_mdep_role_t; - -typedef enum { - BTHL_APP_REG_STATE_REG_SUCCESS, - BTHL_APP_REG_STATE_REG_FAILED, - BTHL_APP_REG_STATE_DEREG_SUCCESS, - BTHL_APP_REG_STATE_DEREG_FAILED -} bthl_app_reg_state_t; - -typedef enum -{ - BTHL_CHANNEL_TYPE_RELIABLE, - BTHL_CHANNEL_TYPE_STREAMING, - BTHL_CHANNEL_TYPE_ANY -} bthl_channel_type_t; - - -/* HL connection states */ -typedef enum { - BTHL_CONN_STATE_CONNECTING, - BTHL_CONN_STATE_CONNECTED, - BTHL_CONN_STATE_DISCONNECTING, - BTHL_CONN_STATE_DISCONNECTED, - BTHL_CONN_STATE_DESTROYED -} bthl_channel_state_t; - -typedef struct -{ - bthl_mdep_role_t mdep_role; - int data_type; - bthl_channel_type_t channel_type; - const char *mdep_description; /* MDEP description to be used in the SDP (optional); null terminated */ -} bthl_mdep_cfg_t; - -typedef struct -{ - const char *application_name; - const char *provider_name; /* provider name to be used in the SDP (optional); null terminated */ - const char *srv_name; /* service name to be used in the SDP (optional); null terminated*/ - const char *srv_desp; /* service description to be used in the SDP (optional); null terminated */ - int number_of_mdeps; - bthl_mdep_cfg_t *mdep_cfg; /* Dynamic array */ -} bthl_reg_param_t; - -/** Callback for application registration status. - * state will have one of the values from bthl_app_reg_state_t - */ -typedef void (* bthl_app_reg_state_callback)(int app_id, bthl_app_reg_state_t state); - -/** Callback for channel connection state change. - * state will have one of the values from - * bthl_connection_state_t and fd (file descriptor) - */ -typedef void (* bthl_channel_state_callback)(int app_id, RawAddress *bd_addr, int mdep_cfg_index, int channel_id, bthl_channel_state_t state, int fd); - -/** BT-HL callback structure. */ -typedef struct { - /** set to sizeof(bthl_callbacks_t) */ - size_t size; - bthl_app_reg_state_callback app_reg_state_cb; - bthl_channel_state_callback channel_state_cb; -} bthl_callbacks_t; - - -/** Represents the standard BT-HL interface. */ -typedef struct { - - /** set to sizeof(bthl_interface_t) */ - size_t size; - - /** - * Register the Bthl callbacks - */ - bt_status_t (*init)( bthl_callbacks_t* callbacks ); - - /** Register HL application */ - bt_status_t (*register_application) ( bthl_reg_param_t *p_reg_param, int *app_id); - - /** Unregister HL application */ - bt_status_t (*unregister_application) (int app_id); - - /** connect channel */ - bt_status_t (*connect_channel)(int app_id, RawAddress *bd_addr, int mdep_cfg_index, int *channel_id); - - /** destroy channel */ - bt_status_t (*destroy_channel)(int channel_id); - - /** Close the Bthl callback **/ - void (*cleanup)(void); - -} bthl_interface_t; -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_HL_H */ - - diff --git a/include/hardware/bt_mce.h b/include/hardware/bt_mce.h deleted file mode 100644 index 406a26a3..00000000 --- a/include/hardware/bt_mce.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2014 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_INCLUDE_BT_MCE_H -#define ANDROID_INCLUDE_BT_MCE_H - -__BEGIN_DECLS - -/** MAS instance description */ -typedef struct -{ - int id; - int scn; - int msg_types; - char *p_name; -} btmce_mas_instance_t; - -/** callback for get_remote_mas_instances */ -typedef void (*btmce_remote_mas_instances_callback)(bt_status_t status, RawAddress *bd_addr, - int num_instances, btmce_mas_instance_t *instances); - -typedef struct { - /** set to sizeof(btmce_callbacks_t) */ - size_t size; - btmce_remote_mas_instances_callback remote_mas_instances_cb; -} btmce_callbacks_t; - -typedef struct { - /** set to size of this struct */ - size_t size; - - /** register BT MCE callbacks */ - bt_status_t (*init)(btmce_callbacks_t *callbacks); - - /** search for MAS instances on remote device */ - bt_status_t (*get_remote_mas_instances)(RawAddress *bd_addr); -} btmce_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_MCE_H */ diff --git a/include/hardware/bt_pan.h b/include/hardware/bt_pan.h deleted file mode 100644 index 2f2e2e56..00000000 --- a/include/hardware/bt_pan.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_PAN_H -#define ANDROID_INCLUDE_BT_PAN_H - -__BEGIN_DECLS - -#define BTPAN_ROLE_NONE 0 -#define BTPAN_ROLE_PANNAP 1 -#define BTPAN_ROLE_PANU 2 - -typedef enum { - BTPAN_STATE_CONNECTED = 0, - BTPAN_STATE_CONNECTING = 1, - BTPAN_STATE_DISCONNECTED = 2, - BTPAN_STATE_DISCONNECTING = 3 -} btpan_connection_state_t; - -typedef enum { - BTPAN_STATE_ENABLED = 0, - BTPAN_STATE_DISABLED = 1 -} btpan_control_state_t; - -/** -* Callback for pan connection state -*/ -typedef void (*btpan_connection_state_callback)(btpan_connection_state_t state, bt_status_t error, - const RawAddress *bd_addr, int local_role, int remote_role); -typedef void (*btpan_control_state_callback)(btpan_control_state_t state, int local_role, - bt_status_t error, const char* ifname); - -typedef struct { - size_t size; - btpan_control_state_callback control_state_cb; - btpan_connection_state_callback connection_state_cb; -} btpan_callbacks_t; -typedef struct { - /** set to size of this struct*/ - size_t size; - /** - * Initialize the pan interface and register the btpan callbacks - */ - bt_status_t (*init)(const btpan_callbacks_t* callbacks); - /* - * enable the pan service by specified role. The result state of - * enabl will be returned by btpan_control_state_callback. when pan-nap is enabled, - * the state of connecting panu device will be notified by btpan_connection_state_callback - */ - bt_status_t (*enable)(int local_role); - /* - * get current pan local role - */ - int (*get_local_role)(void); - /** - * start bluetooth pan connection to the remote device by specified pan role. The result state will be - * returned by btpan_connection_state_callback - */ - bt_status_t (*connect)(const RawAddress *bd_addr, int local_role, int remote_role); - /** - * stop bluetooth pan connection. The result state will be returned by btpan_connection_state_callback - */ - bt_status_t (*disconnect)(const RawAddress *bd_addr); - - /** - * Cleanup the pan interface - */ - void (*cleanup)(void); - -} btpan_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_PAN_H */ diff --git a/include/hardware/bt_rc.h b/include/hardware/bt_rc.h deleted file mode 100644 index 93fb32f0..00000000 --- a/include/hardware/bt_rc.h +++ /dev/null @@ -1,649 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef ANDROID_INCLUDE_BT_RC_H -#define ANDROID_INCLUDE_BT_RC_H - -__BEGIN_DECLS - -/* Change this macro to use multiple RC */ -#define BT_RC_NUM_APP 1 - -/* Macros */ -#define BTRC_MAX_ATTR_STR_LEN (1 << 16) -#define BTRC_UID_SIZE 8 -#define BTRC_MAX_APP_SETTINGS 8 -#define BTRC_MAX_FOLDER_DEPTH 4 -#define BTRC_MAX_APP_ATTR_SIZE 16 -#define BTRC_MAX_ELEM_ATTR_SIZE 8 -#define BTRC_FEATURE_BIT_MASK_SIZE 16 - -/* Macros for valid scopes in get_folder_items */ -#define BTRC_SCOPE_PLAYER_LIST 0x00 /* Media Player List */ -#define BTRC_SCOPE_FILE_SYSTEM 0x01 /* Virtual File System */ -#define BTRC_SCOPE_SEARCH 0x02 /* Search */ -#define BTRC_SCOPE_NOW_PLAYING 0x03 /* Now Playing */ - -/* Macros for supported character encoding */ -#define BTRC_CHARSET_ID_UTF8 0x006A - -/* Macros for item types */ -#define BTRC_ITEM_PLAYER 0x01 /* Media Player */ -#define BTRC_ITEM_FOLDER 0x02 /* Folder */ -#define BTRC_ITEM_MEDIA 0x03 /* Media File */ - -/* Macros for media attribute IDs */ -#define BTRC_MEDIA_ATTR_ID_INVALID -1 -#define BTRC_MEDIA_ATTR_ID_TITLE 0x00000001 -#define BTRC_MEDIA_ATTR_ID_ARTIST 0x00000002 -#define BTRC_MEDIA_ATTR_ID_ALBUM 0x00000003 -#define BTRC_MEDIA_ATTR_ID_TRACK_NUM 0x00000004 -#define BTRC_MEDIA_ATTR_ID_NUM_TRACKS 0x00000005 -#define BTRC_MEDIA_ATTR_ID_GENRE 0x00000006 -#define BTRC_MEDIA_ATTR_ID_PLAYING_TIME 0x00000007 /* in miliseconds */ - -/* Macros for folder types */ -#define BTRC_FOLDER_TYPE_MIXED 0x00 -#define BTRC_FOLDER_TYPE_TITLES 0x01 -#define BTRC_FOLDER_TYPE_ALBUMS 0x02 -#define BTRC_FOLDER_TYPE_ARTISTS 0x03 -#define BTRC_FOLDER_TYPE_GENRES 0x04 -#define BTRC_FOLDER_TYPE_PLAYLISTS 0x05 -#define BTRC_FOLDER_TYPE_YEARS 0x06 - -/* Macros for media types */ -#define BTRC_MEDIA_TYPE_AUDIO 0x00 /* audio */ -#define BTRC_MEDIA_TYPE_VIDEO 0x01 /* video */ - -/* Macros for num attributes */ -#define BTRC_NUM_ATTR_NONE 0xFF /* No attributes required */ -#define BTRC_NUM_ATTR_ALL 0X00 /* All attributes required */ - -#define BTRC_HANDLE_NONE 0xFF - -typedef uint8_t btrc_uid_t[BTRC_UID_SIZE]; - -typedef enum { - BTRC_CONNECTION_STATE_DISCONNECTED = 0, - BTRC_CONNECTION_STATE_CONNECTED -} btrc_connection_state_t; - -typedef enum { - BTRC_FEAT_NONE = 0x00, /* AVRCP 1.0 */ - BTRC_FEAT_METADATA = 0x01, /* AVRCP 1.3 */ - BTRC_FEAT_ABSOLUTE_VOLUME = 0x02, /* Supports TG role and volume sync */ - BTRC_FEAT_BROWSE = 0x04, /* AVRCP 1.4 and up, with Browsing support */ -} btrc_remote_features_t; - -typedef enum { - BTRC_PLAYSTATE_STOPPED = 0x00, /* Stopped */ - BTRC_PLAYSTATE_PLAYING = 0x01, /* Playing */ - BTRC_PLAYSTATE_PAUSED = 0x02, /* Paused */ - BTRC_PLAYSTATE_FWD_SEEK = 0x03, /* Fwd Seek*/ - BTRC_PLAYSTATE_REV_SEEK = 0x04, /* Rev Seek*/ - BTRC_PLAYSTATE_ERROR = 0xFF, /* Error */ -} btrc_play_status_t; - -typedef enum { - BTRC_EVT_PLAY_STATUS_CHANGED = 0x01, - BTRC_EVT_TRACK_CHANGE = 0x02, - BTRC_EVT_TRACK_REACHED_END = 0x03, - BTRC_EVT_TRACK_REACHED_START = 0x04, - BTRC_EVT_PLAY_POS_CHANGED = 0x05, - BTRC_EVT_APP_SETTINGS_CHANGED = 0x08, - BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED = 0x09, - BTRC_EVT_AVAL_PLAYER_CHANGE = 0x0a, - BTRC_EVT_ADDR_PLAYER_CHANGE = 0x0b, - BTRC_EVT_UIDS_CHANGED = 0x0c, - BTRC_EVT_VOL_CHANGED = 0x0d, -} btrc_event_id_t; - -typedef enum { - BTRC_NOTIFICATION_TYPE_INTERIM = 0, - BTRC_NOTIFICATION_TYPE_CHANGED = 1, -} btrc_notification_type_t; - -typedef enum { - BTRC_PLAYER_ATTR_EQUALIZER = 0x01, - BTRC_PLAYER_ATTR_REPEAT = 0x02, - BTRC_PLAYER_ATTR_SHUFFLE = 0x03, - BTRC_PLAYER_ATTR_SCAN = 0x04, -} btrc_player_attr_t; - -typedef enum { - BTRC_MEDIA_ATTR_TITLE = 0x01, - BTRC_MEDIA_ATTR_ARTIST = 0x02, - BTRC_MEDIA_ATTR_ALBUM = 0x03, - BTRC_MEDIA_ATTR_TRACK_NUM = 0x04, - BTRC_MEDIA_ATTR_NUM_TRACKS = 0x05, - BTRC_MEDIA_ATTR_GENRE = 0x06, - BTRC_MEDIA_ATTR_PLAYING_TIME = 0x07, -} btrc_media_attr_t; - -typedef enum { - BTRC_PLAYER_VAL_OFF_REPEAT = 0x01, - BTRC_PLAYER_VAL_SINGLE_REPEAT = 0x02, - BTRC_PLAYER_VAL_ALL_REPEAT = 0x03, - BTRC_PLAYER_VAL_GROUP_REPEAT = 0x04 -} btrc_player_repeat_val_t; - -typedef enum { - BTRC_PLAYER_VAL_OFF_SHUFFLE = 0x01, - BTRC_PLAYER_VAL_ALL_SHUFFLE = 0x02, - BTRC_PLAYER_VAL_GROUP_SHUFFLE = 0x03 -} btrc_player_shuffle_val_t; - -typedef enum { - BTRC_STS_BAD_CMD = 0x00, /* Invalid command */ - BTRC_STS_BAD_PARAM = 0x01, /* Invalid parameter */ - BTRC_STS_NOT_FOUND = 0x02, /* Specified parameter is wrong or not found */ - BTRC_STS_INTERNAL_ERR = 0x03, /* Internal Error */ - BTRC_STS_NO_ERROR = 0x04, /* Operation Success */ - BTRC_STS_UID_CHANGED = 0x05, /* UIDs changed */ - BTRC_STS_RESERVED = 0x06, /* Reserved */ - BTRC_STS_INV_DIRN = 0x07, /* Invalid direction */ - BTRC_STS_INV_DIRECTORY = 0x08, /* Invalid directory */ - BTRC_STS_INV_ITEM = 0x09, /* Invalid Item */ - BTRC_STS_INV_SCOPE = 0x0a, /* Invalid scope */ - BTRC_STS_INV_RANGE = 0x0b, /* Invalid range */ - BTRC_STS_DIRECTORY = 0x0c, /* UID is a directory */ - BTRC_STS_MEDIA_IN_USE = 0x0d, /* Media in use */ - BTRC_STS_PLAY_LIST_FULL = 0x0e, /* Playing list full */ - BTRC_STS_SRCH_NOT_SPRTD = 0x0f, /* Search not supported */ - BTRC_STS_SRCH_IN_PROG = 0x10, /* Search in progress */ - BTRC_STS_INV_PLAYER = 0x11, /* Invalid player */ - BTRC_STS_PLAY_NOT_BROW = 0x12, /* Player not browsable */ - BTRC_STS_PLAY_NOT_ADDR = 0x13, /* Player not addressed */ - BTRC_STS_INV_RESULTS = 0x14, /* Invalid results */ - BTRC_STS_NO_AVBL_PLAY = 0x15, /* No available players */ - BTRC_STS_ADDR_PLAY_CHGD = 0x16, /* Addressed player changed */ -} btrc_status_t; - -typedef struct { - uint16_t player_id; - uint16_t uid_counter; -} btrc_addr_player_changed_t; - -typedef struct { - uint8_t num_attr; - uint8_t attr_ids[BTRC_MAX_APP_SETTINGS]; - uint8_t attr_values[BTRC_MAX_APP_SETTINGS]; -} btrc_player_settings_t; - -typedef struct { - uint8_t val; - uint16_t charset_id; - uint16_t str_len; - uint8_t *p_str; -} btrc_player_app_ext_attr_val_t; - -typedef struct { - uint8_t attr_id; - uint16_t charset_id; - uint16_t str_len; - uint8_t *p_str; - uint8_t num_val; - btrc_player_app_ext_attr_val_t ext_attr_val[BTRC_MAX_APP_ATTR_SIZE]; -} btrc_player_app_ext_attr_t; - -typedef struct { - uint8_t attr_id; - uint8_t num_val; - uint8_t attr_val[BTRC_MAX_APP_ATTR_SIZE]; -} btrc_player_app_attr_t; - -typedef struct { - uint32_t start_item; - uint32_t end_item; - uint32_t size; - uint32_t attrs[BTRC_MAX_ELEM_ATTR_SIZE]; - uint8_t attr_count; -} btrc_getfolderitem_t; - -typedef struct { - uint16_t type; - uint16_t uid_counter; -} btrc_uids_changed_t; - -typedef struct { - uint16_t type; -} btrc_now_playing_changed_t; - -typedef union -{ - btrc_play_status_t play_status; - btrc_uid_t track; /* queue position in NowPlaying */ - uint32_t song_pos; - uint16_t uid_counter; - btrc_player_settings_t player_setting; - btrc_addr_player_changed_t addr_player_changed; - btrc_uids_changed_t uids_changed; - btrc_now_playing_changed_t now_playing_changed; -} btrc_register_notification_t; - -typedef struct { - uint8_t id; /* can be attr_id or value_id */ - uint8_t text[BTRC_MAX_ATTR_STR_LEN]; -} btrc_player_setting_text_t; - -typedef struct { - uint32_t attr_id; - uint8_t text[BTRC_MAX_ATTR_STR_LEN]; -} btrc_element_attr_val_t; - -typedef struct { - uint16_t player_id; - uint8_t major_type; - uint32_t sub_type; - uint8_t play_status; - uint8_t features[BTRC_FEATURE_BIT_MASK_SIZE]; - uint16_t charset_id; - uint8_t name[BTRC_MAX_ATTR_STR_LEN]; -} btrc_item_player_t; - -typedef struct { - uint8_t uid[BTRC_UID_SIZE]; - uint8_t type; - uint8_t playable; - uint16_t charset_id; - uint8_t name[BTRC_MAX_ATTR_STR_LEN]; -} btrc_item_folder_t; - -typedef struct { - uint8_t uid[BTRC_UID_SIZE]; - uint8_t type; - uint16_t charset_id; - uint8_t name[BTRC_MAX_ATTR_STR_LEN]; - int num_attrs; - btrc_element_attr_val_t* p_attrs; -} btrc_item_media_t; - -typedef struct { - uint8_t item_type; - union - { - btrc_item_player_t player; - btrc_item_folder_t folder; - btrc_item_media_t media; - }; -} btrc_folder_items_t; - -typedef struct { - uint16_t str_len; - uint8_t p_str[BTRC_MAX_ATTR_STR_LEN]; -} btrc_br_folder_name_t; - -/** Callback for the controller's supported feautres */ -typedef void (* btrc_remote_features_callback)(RawAddress *bd_addr, - btrc_remote_features_t features); - -/** Callback for play status request */ -typedef void (* btrc_get_play_status_callback)(RawAddress *bd_addr); - -/** Callback for list player application attributes (Shuffle, Repeat,...) */ -typedef void (* btrc_list_player_app_attr_callback)(RawAddress *bd_addr); - -/** Callback for list player application attributes (Shuffle, Repeat,...) */ -typedef void (* btrc_list_player_app_values_callback)(btrc_player_attr_t attr_id, - RawAddress *bd_addr); - -/** Callback for getting the current player application settings value -** num_attr: specifies the number of attribute ids contained in p_attrs -*/ -typedef void (* btrc_get_player_app_value_callback) (uint8_t num_attr, - btrc_player_attr_t *p_attrs, RawAddress *bd_addr); - -/** Callback for getting the player application settings attributes' text -** num_attr: specifies the number of attribute ids contained in p_attrs -*/ -typedef void (* btrc_get_player_app_attrs_text_callback) (uint8_t num_attr, - btrc_player_attr_t *p_attrs, RawAddress *bd_addr); - -/** Callback for getting the player application settings values' text -** num_attr: specifies the number of value ids contained in p_vals -*/ -typedef void (* btrc_get_player_app_values_text_callback) (uint8_t attr_id, uint8_t num_val, - uint8_t *p_vals, RawAddress *bd_addr); - -/** Callback for setting the player application settings values */ -typedef void (* btrc_set_player_app_value_callback) (btrc_player_settings_t *p_vals, - RawAddress *bd_addr); - -/** Callback to fetch the get element attributes of the current song -** num_attr: specifies the number of attributes requested in p_attrs -*/ -typedef void (* btrc_get_element_attr_callback) (uint8_t num_attr, btrc_media_attr_t *p_attrs, - RawAddress *bd_addr); - -/** Callback for register notification (Play state change/track change/...) -** param: Is only valid if event_id is BTRC_EVT_PLAY_POS_CHANGED -*/ -typedef void (* btrc_register_notification_callback) (btrc_event_id_t event_id, uint32_t param, - RawAddress *bd_addr); - -/* AVRCP 1.4 Enhancements */ -/** Callback for volume change on CT -** volume: Current volume setting on the CT (0-127) -*/ -typedef void (* btrc_volume_change_callback) (uint8_t volume, uint8_t ctype, RawAddress *bd_addr); - -/** Callback for passthrough commands */ -typedef void (* btrc_passthrough_cmd_callback) (int id, int key_state, RawAddress *bd_addr); - -/** Callback for set addressed player response on TG **/ -typedef void (* btrc_set_addressed_player_callback) (uint16_t player_id, RawAddress *bd_addr); - -/** Callback for set browsed player response on TG **/ -typedef void (* btrc_set_browsed_player_callback) (uint16_t player_id, RawAddress *bd_addr); - -/** Callback for get folder items on TG -** num_attr: specifies the number of attributes requested in p_attr_ids -*/ -typedef void (* btrc_get_folder_items_callback) (uint8_t scope, uint32_t start_item, - uint32_t end_item, uint8_t num_attr, uint32_t *p_attr_ids, RawAddress *bd_addr); - -/** Callback for changing browsed path on TG **/ -typedef void (* btrc_change_path_callback) (uint8_t direction, - uint8_t* folder_uid, RawAddress *bd_addr); - -/** Callback to fetch the get item attributes of the media item -** num_attr: specifies the number of attributes requested in p_attrs -*/ -typedef void (* btrc_get_item_attr_callback) (uint8_t scope, uint8_t* uid, uint16_t uid_counter, - uint8_t num_attr, btrc_media_attr_t *p_attrs, RawAddress *bd_addr); - -/** Callback for play request for the media item indicated by an identifier */ -typedef void (* btrc_play_item_callback) (uint8_t scope, - uint16_t uid_counter, uint8_t* uid, RawAddress *bd_addr); - -/** Callback to fetch total number of items from a folder **/ -typedef void (* btrc_get_total_num_of_items_callback) (uint8_t scope, RawAddress *bd_addr); - -/** Callback for conducting recursive search on a current browsed path for a specified string */ -typedef void (* btrc_search_callback) (uint16_t charset_id, - uint16_t str_len, uint8_t* p_str, RawAddress *bd_addr); - -/** Callback to add a specified media item indicated by an identifier to now playing queue. */ -typedef void (* btrc_add_to_now_playing_callback) (uint8_t scope, - uint8_t* uid, uint16_t uid_counter, RawAddress *bd_addr); - -/** BT-RC Target callback structure. */ -typedef struct { - /** set to sizeof(BtRcCallbacks) */ - size_t size; - btrc_remote_features_callback remote_features_cb; - btrc_get_play_status_callback get_play_status_cb; - btrc_list_player_app_attr_callback list_player_app_attr_cb; - btrc_list_player_app_values_callback list_player_app_values_cb; - btrc_get_player_app_value_callback get_player_app_value_cb; - btrc_get_player_app_attrs_text_callback get_player_app_attrs_text_cb; - btrc_get_player_app_values_text_callback get_player_app_values_text_cb; - btrc_set_player_app_value_callback set_player_app_value_cb; - btrc_get_element_attr_callback get_element_attr_cb; - btrc_register_notification_callback register_notification_cb; - btrc_volume_change_callback volume_change_cb; - btrc_passthrough_cmd_callback passthrough_cmd_cb; - btrc_set_addressed_player_callback set_addressed_player_cb; - btrc_set_browsed_player_callback set_browsed_player_cb; - btrc_get_folder_items_callback get_folder_items_cb; - btrc_change_path_callback change_path_cb; - btrc_get_item_attr_callback get_item_attr_cb; - btrc_play_item_callback play_item_cb; - btrc_get_total_num_of_items_callback get_total_num_of_items_cb; - btrc_search_callback search_cb; - btrc_add_to_now_playing_callback add_to_now_playing_cb; -} btrc_callbacks_t; - -/** Represents the standard BT-RC AVRCP Target interface. */ -typedef struct { - - /** set to sizeof(BtRcInterface) */ - size_t size; - /** - * Register the BtRc callbacks - */ - bt_status_t (*init)( btrc_callbacks_t* callbacks ); - - /** Respose to GetPlayStatus request. Contains the current - ** 1. Play status - ** 2. Song duration/length - ** 3. Song position - */ - bt_status_t (*get_play_status_rsp)( RawAddress *bd_addr, btrc_play_status_t play_status, - uint32_t song_len, uint32_t song_pos); - - /** Lists the support player application attributes (Shuffle/Repeat/...) - ** num_attr: Specifies the number of attributes contained in the pointer p_attrs - */ - bt_status_t (*list_player_app_attr_rsp)( RawAddress *bd_addr, int num_attr, - btrc_player_attr_t *p_attrs); - - /** Lists the support player application attributes (Shuffle Off/On/Group) - ** num_val: Specifies the number of values contained in the pointer p_vals - */ - bt_status_t (*list_player_app_value_rsp)( RawAddress *bd_addr, int num_val, uint8_t *p_vals); - - /** Returns the current application attribute values for each of the specified attr_id */ - bt_status_t (*get_player_app_value_rsp)( RawAddress *bd_addr, btrc_player_settings_t *p_vals); - - /** Returns the application attributes text ("Shuffle"/"Repeat"/...) - ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs - */ - bt_status_t (*get_player_app_attr_text_rsp)( RawAddress *bd_addr, int num_attr, - btrc_player_setting_text_t *p_attrs); - - /** Returns the application attributes text ("Shuffle"/"Repeat"/...) - ** num_attr: Specifies the number of attribute values' text contained in the pointer p_vals - */ - bt_status_t (*get_player_app_value_text_rsp)( RawAddress *bd_addr, int num_val, - btrc_player_setting_text_t *p_vals); - - /** Returns the current songs' element attributes text ("Title"/"Album"/"Artist") - ** num_attr: Specifies the number of attributes' text contained in the pointer p_attrs - */ - bt_status_t (*get_element_attr_rsp)( RawAddress *bd_addr, uint8_t num_attr, - btrc_element_attr_val_t *p_attrs); - - /** Response to set player attribute request ("Shuffle"/"Repeat") - ** rsp_status: Status of setting the player attributes for the current media player - */ - bt_status_t (*set_player_app_value_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status); - - /* Response to the register notification request (Play state change/track change/...). - ** event_id: Refers to the event_id this notification change corresponds too - ** type: Response type - interim/changed - ** p_params: Based on the event_id, this parameter should be populated - */ - bt_status_t (*register_notification_rsp)(btrc_event_id_t event_id, - btrc_notification_type_t type, - btrc_register_notification_t *p_param); - - /* AVRCP 1.4 enhancements */ - - /**Send current volume setting to remote side. Support limited to SetAbsoluteVolume - ** This can be enhanced to support Relative Volume (AVRCP 1.0). - ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN opposed to absolute volume level - ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set - */ - bt_status_t (*set_volume)(uint8_t volume); - - /* Set addressed player response from TG to CT */ - bt_status_t (*set_addressed_player_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status); - - /* Set browsed player response from TG to CT */ - bt_status_t (*set_browsed_player_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, - uint32_t num_items, uint16_t charset_id, uint8_t folder_depth, - btrc_br_folder_name_t *p_folders); - - /* Get folder item list response from TG to CT */ - bt_status_t (*get_folder_items_list_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, - uint16_t uid_counter, uint8_t num_items, btrc_folder_items_t *p_items); - - /* Change path response from TG to CT */ - bt_status_t (*change_path_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, - uint32_t num_items); - - /** Returns the element's attributes num_attr: Specifies the number of attributes' text - * contained in the pointer p_attrs - */ - bt_status_t (*get_item_attr_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, - uint8_t num_attr, btrc_element_attr_val_t *p_attrs); - - /* play media item response from TG to CT */ - bt_status_t (*play_item_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status); - - /* get total number of items response from TG to CT*/ - bt_status_t (*get_total_num_of_items_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, - uint32_t uid_counter, uint32_t num_items); - - /* Search VFS response from TG to CT */ - bt_status_t (*search_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status, uint32_t uid_counter, - uint32_t num_items); - - /* add_to_now playing list response from TG to CT */ - bt_status_t (*add_to_now_playing_rsp)(RawAddress *bd_addr, btrc_status_t rsp_status); - - /** Closes the interface. */ - void (*cleanup)( void ); -} btrc_interface_t; - -typedef void (* btrc_passthrough_rsp_callback) (RawAddress *bd_addr, int id, int key_state); - -typedef void (* btrc_groupnavigation_rsp_callback) (int id, int key_state); - -typedef void (* btrc_connection_state_callback) ( - bool rc_connect, bool bt_connect, RawAddress *bd_addr); - -typedef void (* btrc_ctrl_getrcfeatures_callback) (RawAddress *bd_addr, int features); - -typedef void (* btrc_ctrl_setabsvol_cmd_callback) (RawAddress *bd_addr, uint8_t abs_vol, uint8_t label); - -typedef void (* btrc_ctrl_registernotification_abs_vol_callback) (RawAddress *bd_addr, uint8_t label); - -typedef void (* btrc_ctrl_setplayerapplicationsetting_rsp_callback) (RawAddress *bd_addr, - uint8_t accepted); - -typedef void (* btrc_ctrl_playerapplicationsetting_callback)(RawAddress *bd_addr, - uint8_t num_attr, - btrc_player_app_attr_t *app_attrs, - uint8_t num_ext_attr, - btrc_player_app_ext_attr_t *ext_attrs); - -typedef void (* btrc_ctrl_playerapplicationsetting_changed_callback)(RawAddress *bd_addr, - btrc_player_settings_t *p_vals); - -typedef void (* btrc_ctrl_track_changed_callback)(RawAddress *bd_addr, uint8_t num_attr, - btrc_element_attr_val_t *p_attrs); - -typedef void (* btrc_ctrl_play_position_changed_callback)(RawAddress *bd_addr, - uint32_t song_len, uint32_t song_pos); - -typedef void (* btrc_ctrl_play_status_changed_callback)(RawAddress *bd_addr, - btrc_play_status_t play_status); - -typedef void (* btrc_ctrl_get_folder_items_callback )(RawAddress *bd_addr, - btrc_status_t status, - const btrc_folder_items_t *folder_items, - uint8_t count); - -typedef void (* btrc_ctrl_change_path_callback)(RawAddress *bd_addr, uint8_t count); - -typedef void (* btrc_ctrl_set_browsed_player_callback )( - RawAddress *bd_addr, uint8_t num_items, uint8_t depth); -typedef void (* btrc_ctrl_set_addressed_player_callback)(RawAddress *bd_addr, uint8_t status); -/** BT-RC Controller callback structure. */ -typedef struct { - /** set to sizeof(BtRcCallbacks) */ - size_t size; - btrc_passthrough_rsp_callback passthrough_rsp_cb; - btrc_groupnavigation_rsp_callback groupnavigation_rsp_cb; - btrc_connection_state_callback connection_state_cb; - btrc_ctrl_getrcfeatures_callback getrcfeatures_cb; - btrc_ctrl_setplayerapplicationsetting_rsp_callback setplayerappsetting_rsp_cb; - btrc_ctrl_playerapplicationsetting_callback playerapplicationsetting_cb; - btrc_ctrl_playerapplicationsetting_changed_callback playerapplicationsetting_changed_cb; - btrc_ctrl_setabsvol_cmd_callback setabsvol_cmd_cb; - btrc_ctrl_registernotification_abs_vol_callback registernotification_absvol_cb; - btrc_ctrl_track_changed_callback track_changed_cb; - btrc_ctrl_play_position_changed_callback play_position_changed_cb; - btrc_ctrl_play_status_changed_callback play_status_changed_cb; - btrc_ctrl_get_folder_items_callback get_folder_items_cb; - btrc_ctrl_change_path_callback change_folder_path_cb; - btrc_ctrl_set_browsed_player_callback set_browsed_player_cb; - btrc_ctrl_set_addressed_player_callback set_addressed_player_cb; -} btrc_ctrl_callbacks_t; - -/** Represents the standard BT-RC AVRCP Controller interface. */ -typedef struct { - - /** set to sizeof(BtRcInterface) */ - size_t size; - /** - * Register the BtRc callbacks - */ - bt_status_t (*init)( btrc_ctrl_callbacks_t* callbacks ); - - /** send pass through command to target */ - bt_status_t (*send_pass_through_cmd) (RawAddress *bd_addr, uint8_t key_code, - uint8_t key_state ); - - /** send group navigation command to target */ - bt_status_t (*send_group_navigation_cmd) (RawAddress *bd_addr, uint8_t key_code, - uint8_t key_state ); - - /** send command to set player applicaiton setting attributes to target */ - bt_status_t (*set_player_app_setting_cmd) (RawAddress *bd_addr, uint8_t num_attrib, - uint8_t* attrib_ids, uint8_t* attrib_vals); - - /** send command to play a particular item */ - bt_status_t (*play_item_cmd) ( - RawAddress *bd_addr, uint8_t scope, uint8_t *uid, uint16_t uid_counter); - - /** get the playback state */ - bt_status_t (*get_playback_state_cmd) (RawAddress *bd_addr); - - /** get the now playing list */ - bt_status_t (*get_now_playing_list_cmd) (RawAddress *bd_addr, uint8_t start, uint8_t items); - - /** get the folder list */ - bt_status_t (*get_folder_list_cmd) (RawAddress *bd_addr, uint8_t start, uint8_t items); - - /** get the folder list */ - bt_status_t (*get_player_list_cmd) (RawAddress *bd_addr, uint8_t start, uint8_t items); - - /** get the folder list */ - bt_status_t (*change_folder_path_cmd) (RawAddress *bd_addr, uint8_t direction, uint8_t * uid); - - /** set browsed player */ - bt_status_t (*set_browsed_player_cmd) (RawAddress *bd_addr, uint16_t player_id); - - /** set addressed player */ - bt_status_t (*set_addressed_player_cmd) (RawAddress *bd_addr, uint16_t player_id); - - /** send rsp to set_abs_vol received from target */ - bt_status_t (*set_volume_rsp) (RawAddress *bd_addr, uint8_t abs_vol, uint8_t label); - - /** send notificaiton rsp for abs vol to target */ - bt_status_t (*register_abs_vol_rsp) (RawAddress *bd_addr, btrc_notification_type_t rsp_type, - uint8_t abs_vol, uint8_t label); - - /** Closes the interface. */ - void (*cleanup)( void ); -} btrc_ctrl_interface_t; - -__END_DECLS - -#endif /* ANDROID_INCLUDE_BT_RC_H */ diff --git a/include/hardware/bt_sdp.h b/include/hardware/bt_sdp.h deleted file mode 100644 index 7db71394..00000000 --- a/include/hardware/bt_sdp.h +++ /dev/null @@ -1,154 +0,0 @@ -/* - * Copyright (C) 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. - */ - -#pragma once - -#include "bluetooth.h" - -#define SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH 15 - -__BEGIN_DECLS - -/** - * These events are handled by the state machine - */ -typedef enum { - SDP_TYPE_RAW, // Used to carry raw SDP search data for unknown UUIDs - SDP_TYPE_MAP_MAS, // Message Access Profile - Server - SDP_TYPE_MAP_MNS, // Message Access Profile - Client (Notification Server) - SDP_TYPE_PBAP_PSE, // Phone Book Profile - Server - SDP_TYPE_PBAP_PCE, // Phone Book Profile - Client - SDP_TYPE_OPP_SERVER, // Object Push Profile - SDP_TYPE_SAP_SERVER // SIM Access Profile -} bluetooth_sdp_types; - -typedef struct _bluetooth_sdp_hdr { - bluetooth_sdp_types type; - bluetooth::Uuid uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; -} bluetooth_sdp_hdr; - -/** - * Some signals need additional pointers, hence we introduce a - * generic way to handle these pointers. - */ -typedef struct _bluetooth_sdp_hdr_overlay { - bluetooth_sdp_types type; - bluetooth::Uuid uuid; - uint32_t service_name_length; - char *service_name; - int32_t rfcomm_channel_number; - int32_t l2cap_psm; - int32_t profile_version; - - // User pointers, only used for some signals - see bluetooth_sdp_ops_record - int user1_ptr_len; - uint8_t *user1_ptr; - int user2_ptr_len; - uint8_t *user2_ptr; -} bluetooth_sdp_hdr_overlay; - -typedef struct _bluetooth_sdp_mas_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t mas_instance_id; - uint32_t supported_features; - uint32_t supported_message_types; -} bluetooth_sdp_mas_record; - -typedef struct _bluetooth_sdp_mns_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; -} bluetooth_sdp_mns_record; - -typedef struct _bluetooth_sdp_pse_record { - bluetooth_sdp_hdr_overlay hdr; - uint32_t supported_features; - uint32_t supported_repositories; -} bluetooth_sdp_pse_record; - -typedef struct _bluetooth_sdp_pce_record { - bluetooth_sdp_hdr_overlay hdr; -} bluetooth_sdp_pce_record; - -typedef struct _bluetooth_sdp_ops_record { - bluetooth_sdp_hdr_overlay hdr; - int supported_formats_list_len; - uint8_t supported_formats_list[SDP_OPP_SUPPORTED_FORMATS_MAX_LENGTH]; -} bluetooth_sdp_ops_record; - -typedef struct _bluetooth_sdp_sap_record { - bluetooth_sdp_hdr_overlay hdr; -} bluetooth_sdp_sap_record; - -typedef union { - bluetooth_sdp_hdr_overlay hdr; - bluetooth_sdp_mas_record mas; - bluetooth_sdp_mns_record mns; - bluetooth_sdp_pse_record pse; - bluetooth_sdp_pce_record pce; - bluetooth_sdp_ops_record ops; - bluetooth_sdp_sap_record sap; -} bluetooth_sdp_record; - - -/** Callback for SDP search */ -typedef void (*btsdp_search_callback)(bt_status_t status, - const RawAddress &bd_addr, - const bluetooth::Uuid &uuid, - int num_records, - bluetooth_sdp_record *records); - -typedef struct { - /** Set to sizeof(btsdp_callbacks_t) */ - size_t size; - btsdp_search_callback sdp_search_cb; -} btsdp_callbacks_t; - -typedef struct { - /** Set to size of this struct */ - size_t size; - - /** Register BT SDP search callbacks */ - bt_status_t (*init)(btsdp_callbacks_t *callbacks); - - /** Unregister BT SDP */ - bt_status_t (*deinit)(); - - /** Search for SDP records with specific uuid on remote device */ - bt_status_t (*sdp_search)(RawAddress *bd_addr, const bluetooth::Uuid& uuid); - - /** - * Use listen in the socket interface to create rfcomm and/or l2cap PSM channels, - * (without UUID and service_name and set the BTSOCK_FLAG_NO_SDP flag in flags). - * Then use createSdpRecord to create the SDP record associated with the rfcomm/l2cap channels. - * - * Returns a handle to the SDP record, which can be parsed to remove_sdp_record. - * - * record (in) The SDP record to create - * record_handle (out)The corresponding record handle will be written to this pointer. - */ - bt_status_t (*create_sdp_record)(bluetooth_sdp_record *record, int* record_handle); - - /** Remove a SDP record created by createSdpRecord */ - bt_status_t (*remove_sdp_record)(int sdp_handle); -} btsdp_interface_t; - -__END_DECLS - diff --git a/include/hardware/bt_sock.h b/include/hardware/bt_sock.h deleted file mode 100644 index 70161a3f..00000000 --- a/include/hardware/bt_sock.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2012 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -__BEGIN_DECLS - -#define BTSOCK_FLAG_ENCRYPT 1 -#define BTSOCK_FLAG_AUTH (1 << 1) -#define BTSOCK_FLAG_NO_SDP (1 << 2) -#define BTSOCK_FLAG_AUTH_MITM (1 << 3) -#define BTSOCK_FLAG_AUTH_16_DIGIT (1 << 4) - -typedef enum { - BTSOCK_RFCOMM = 1, - BTSOCK_SCO = 2, - BTSOCK_L2CAP = 3 -} btsock_type_t; - -/** Represents the standard BT SOCKET interface. */ -typedef struct { - short size; - RawAddress bd_addr; - int channel; - int status; - - // The writer must make writes using a buffer of this maximum size - // to avoid loosing data. (L2CAP only) - unsigned short max_tx_packet_size; - - // The reader must read using a buffer of at least this size to avoid - // loosing data. (L2CAP only) - unsigned short max_rx_packet_size; -} __attribute__((packed)) sock_connect_signal_t; - -typedef struct { - /** set to size of this struct*/ - size_t size; - - /** - * Listen to a RFCOMM UUID or channel. It returns the socket fd from which - * btsock_connect_signal can be read out when a remote device connected. - * If neither a UUID nor a channel is provided, a channel will be allocated - * and a service record can be created providing the channel number to - * create_sdp_record(...) in bt_sdp. - * The callingUid is the UID of the application which is requesting the socket. This is - * used for traffic accounting purposes. - */ - bt_status_t (*listen)(btsock_type_t type, const char* service_name, - const bluetooth::Uuid* service_uuid, int channel, int* sock_fd, int flags, int callingUid); - - /** - * Connect to a RFCOMM UUID channel of remote device, It returns the socket fd from which - * the btsock_connect_signal and a new socket fd to be accepted can be read out when connected. - * The callingUid is the UID of the application which is requesting the socket. This is - * used for traffic accounting purposes. - */ - bt_status_t (*connect)(const RawAddress *bd_addr, btsock_type_t type, const bluetooth::Uuid* uuid, - int channel, int* sock_fd, int flags, int callingUid); -} btsock_interface_t; - -__END_DECLS - From b10ce6d68318780df3bd58f7aad199378e4e264b Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Fri, 27 Oct 2017 19:37:58 -0700 Subject: [PATCH 06/50] USB audio hal - avoid reading alsa profile if input already open Test: USB headset, recording in background, launch another record. Bug: 68211730 Change-Id: I12b5c031b4cb9d2e8228bef7234b3c3b75efc8a2 --- modules/usbaudio/audio_hal.c | 54 ++++++++++++++++++++++++++++++------ 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index e93396ff..9083f324 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -69,6 +69,8 @@ struct audio_device { bool mic_muted; bool standby; + + int32_t inputs_open; /* number of input streams currently open. */ }; struct stream_lock { @@ -787,8 +789,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) 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 */ - if (!in->standby) + /* cannot read pcm device info if playback is active, or more than one open stream */ + if (!in->standby || in->adev->inputs_open > 1) ret_value = -ENOSYS; else { int saved_card = in->profile->card; @@ -940,10 +942,17 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, ALOGV("adev_open_input_stream() rate:%" PRIu32 ", chanMask:0x%" PRIX32 ", fmt:%" PRIu8, config->sample_rate, config->channel_mask, config->format); - struct stream_in *in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); - int ret = 0; + /* Pull out the card/device pair */ + int32_t card, device; + if (!parse_card_device_params(address, &card, &device)) { + ALOGW("%s fail - invalid address %s", __func__, address); + *stream_in = NULL; + return -EINVAL; + } + struct stream_in * const in = (struct stream_in *)calloc(1, sizeof(struct stream_in)); if (in == NULL) { + *stream_in = NULL; return -ENOMEM; } @@ -975,10 +984,29 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, struct pcm_config proxy_config; memset(&proxy_config, 0, sizeof(proxy_config)); - /* Pull out the card/device pair */ - parse_card_device_params(address, &(in->profile->card), &(in->profile->device)); - - profile_read_device_info(in->profile); + int ret = 0; + /* Check if an input stream is already open */ + if (in->adev->inputs_open > 0) { + if (!profile_is_cached_for(in->profile, card, device)) { + ALOGW("%s fail - address card:%d device:%d doesn't match existing profile", + __func__, card, device); + ret = -EINVAL; + } + } else { + /* Read input profile only if necessary */ + in->profile->card = card; + in->profile->device = device; + if (!profile_read_device_info(in->profile)) { + ALOGW("%s fail - cannot read profile", __func__); + ret = -EINVAL; + } + } + if (ret != 0) { + device_unlock(in->adev); + free(in); + *stream_in = NULL; + return ret; + } /* Rate */ if (config->sample_rate == 0) { @@ -1083,6 +1111,10 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, free(in); } + device_lock(in->adev); + ++in->adev->inputs_open; + device_unlock(in->adev); + return ret; } @@ -1094,6 +1126,12 @@ static void adev_close_input_stream(struct audio_hw_device *hw_dev, adev_remove_stream_from_list(in->adev, &in->list_node); + device_lock(in->adev); + --in->adev->inputs_open; + LOG_ALWAYS_FATAL_IF(in->adev->inputs_open < 0, + "invalid inputs_open: %d", in->adev->inputs_open); + device_unlock(in->adev); + /* Close the pcm device */ in_standby(&stream->common); From 4e6a1c01e01f290f40a5f20edf2a83f17a18c75a Mon Sep 17 00:00:00 2001 From: Andy Hung Date: Fri, 27 Oct 2017 20:31:46 -0700 Subject: [PATCH 07/50] USB audio - make profile const Test: Record / Playback audio Bug: 68211730 Change-Id: I73e0a45eb6ea959e784e2a9db67f000badb10d11 --- modules/usbaudio/audio_hal.c | 48 ++++++++++++++++++++++-------------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 9083f324..43d1daf7 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -87,7 +87,12 @@ struct stream_out { 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 */ + const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device. + * Const, so modifications go through adev->out_profile + * and thus should have the hardware lock and ensure + * stream is not active and no other open output streams. + */ + alsa_device_proxy proxy; /* state of the stream */ unsigned hal_channel_count; /* channel count exposed to AudioFlinger. @@ -118,7 +123,12 @@ struct stream_in { 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 */ + const alsa_device_profile *profile; /* Points to the alsa_device_profile in the audio_device. + * Const, so modifications go through adev->out_profile + * and thus should have the hardware lock and ensure + * stream is not active and no other open input streams. + */ + alsa_device_proxy proxy; /* state of the stream */ unsigned hal_channel_count; /* channel count exposed to AudioFlinger. @@ -234,7 +244,7 @@ static bool parse_card_device_params(const char *kvpairs, int *card, int *device return *card >= 0 && *device >= 0; } -static char * device_get_parameters(alsa_device_profile * profile, const char * keys) +static char *device_get_parameters(const alsa_device_profile *profile, const char * keys) { if (profile->card < 0 || profile->device < 0) { return strdup(""); @@ -386,12 +396,12 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) else { int saved_card = out->profile->card; int saved_device = out->profile->device; - out->profile->card = card; - out->profile->device = device; - ret_value = profile_read_device_info(out->profile) ? 0 : -EINVAL; + out->adev->out_profile.card = card; + out->adev->out_profile.device = device; + ret_value = profile_read_device_info(&out->adev->out_profile) ? 0 : -EINVAL; if (ret_value != 0) { - out->profile->card = saved_card; - out->profile->device = saved_device; + out->adev->out_profile.card = saved_card; + out->adev->out_profile.device = saved_device; } } } @@ -574,9 +584,9 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, memset(&proxy_config, 0, sizeof(proxy_config)); /* Pull out the card/device pair */ - parse_card_device_params(address, &(out->profile->card), &(out->profile->device)); + parse_card_device_params(address, &out->adev->out_profile.card, &out->adev->out_profile.device); - profile_read_device_info(out->profile); + profile_read_device_info(&out->adev->out_profile); int ret = 0; @@ -795,12 +805,12 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) else { int saved_card = in->profile->card; int saved_device = in->profile->device; - in->profile->card = card; - in->profile->device = device; - ret_value = profile_read_device_info(in->profile) ? 0 : -EINVAL; + in->adev->in_profile.card = card; + in->adev->in_profile.device = device; + ret_value = profile_read_device_info(&in->adev->in_profile) ? 0 : -EINVAL; if (ret_value != 0) { - in->profile->card = saved_card; - in->profile->device = saved_device; + in->adev->in_profile.card = saved_card; + in->adev->in_profile.device = saved_device; } } } @@ -870,7 +880,7 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte in->standby = false; } - alsa_device_profile * profile = in->profile; + const alsa_device_profile *profile = in->profile; /* * OK, we need to figure out how much data to read to be able to output the requested @@ -994,9 +1004,9 @@ static int adev_open_input_stream(struct audio_hw_device *hw_dev, } } else { /* Read input profile only if necessary */ - in->profile->card = card; - in->profile->device = device; - if (!profile_read_device_info(in->profile)) { + in->adev->in_profile.card = card; + in->adev->in_profile.device = device; + if (!profile_read_device_info(&in->adev->in_profile)) { ALOGW("%s fail - cannot read profile", __func__); ret = -EINVAL; } From 1fc9b614b86534e5173b7861a2f1284d5eedd9de Mon Sep 17 00:00:00 2001 From: Jaesung Chung Date: Fri, 10 Nov 2017 18:09:38 +0900 Subject: [PATCH 08/50] Fix lock mechanism in v4l2 camera HAL Both in_flight_lock_ lock in v4l2_camera.cpp and buffer_queue_lock_ in v4l2_wrapper.cpp have problems that guards the buffer indices and in flight buffer vector incorrectly. Those problem leads to mismatching in terms of buffer size between the HAL and Camera3Device and eventually the Camera3Device will stop to wait for buffers that HAL will not post in the future. Bug: 69076261 Test: Camera samples app doesn't stuck with FB impl. Exempt-From-Owner-Approval: got +2 from the HAL maintainer. Change-Id: I3d0a4361d46571fd144a5eb8bc160296a31d6358 --- modules/camera/3_4/v4l2_camera.cpp | 46 ++++++++++++++++------------- modules/camera/3_4/v4l2_wrapper.cpp | 14 ++++++--- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp index 3e5b8590..2bc0c9f4 100644 --- a/modules/camera/3_4/v4l2_camera.cpp +++ b/modules/camera/3_4/v4l2_camera.cpp @@ -295,32 +295,36 @@ bool V4L2Camera::enqueueRequestBuffers() { bool V4L2Camera::dequeueRequestBuffers() { // Dequeue a buffer. uint32_t result_index; - int res = device_->DequeueBuffer(&result_index); - if (res) { - if (res == -EAGAIN) { - // EAGAIN just means nothing to dequeue right now. - // Wait until something is available before looping again. - std::unique_lock lock(in_flight_lock_); - while (in_flight_.empty()) { - buffers_in_flight_.wait(lock); + int res; + + { + std::lock_guard guard(in_flight_lock_); + res = device_->DequeueBuffer(&result_index); + if (!res) { + // Find the associated request and complete it. + auto index_request = in_flight_.find(result_index); + if (index_request != in_flight_.end()) { + completeRequest(index_request->second, 0); + in_flight_.erase(index_request); + } else { + HAL_LOGW( + "Dequeued non in-flight buffer index %d. " + "This buffer may have been flushed from the HAL but not the device.", + index_request->first); } - } else { - HAL_LOGW("Device failed to dequeue buffer: %d", res); + return true; } - return true; } - // Find the associated request and complete it. - std::lock_guard guard(in_flight_lock_); - auto index_request = in_flight_.find(result_index); - if (index_request != in_flight_.end()) { - completeRequest(index_request->second, 0); - in_flight_.erase(index_request); + if (res == -EAGAIN) { + // EAGAIN just means nothing to dequeue right now. + // Wait until something is available before looping again. + std::unique_lock lock(in_flight_lock_); + while (in_flight_.empty()) { + buffers_in_flight_.wait(lock); + } } else { - HAL_LOGW( - "Dequeued non in-flight buffer index %d. " - "This buffer may have been flushed from the HAL but not the device.", - index_request->first); + HAL_LOGW("Device failed to dequeue buffer: %d", res); } return true; } diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp index 3fafffd2..b5a1c71a 100644 --- a/modules/camera/3_4/v4l2_wrapper.cpp +++ b/modules/camera/3_4/v4l2_wrapper.cpp @@ -535,6 +535,7 @@ int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, std::lock_guard guard(buffer_queue_lock_); for (int i = 0; i < buffers_.size(); ++i) { if (!buffers_[i]) { + buffers_[i] = true; index = i; break; } @@ -557,6 +558,9 @@ int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, // and fill out remaining fields. if (IoctlLocked(VIDIOC_QUERYBUF, &device_buffer) < 0) { HAL_LOGE("QUERYBUF fails: %s", strerror(errno)); + // Return buffer index. + std::lock_guard guard(buffer_queue_lock_); + buffers_[index] = false; return -ENODEV; } @@ -565,18 +569,20 @@ int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer); if (res) { HAL_LOGE("Gralloc failed to lock buffer."); + // Return buffer index. + std::lock_guard guard(buffer_queue_lock_); + buffers_[index] = false; return res; } if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) { HAL_LOGE("QBUF fails: %s", strerror(errno)); gralloc_->unlock(&device_buffer); + // Return buffer index. + std::lock_guard guard(buffer_queue_lock_); + buffers_[index] = false; return -ENODEV; } - // Mark the buffer as in flight. - std::lock_guard guard(buffer_queue_lock_); - buffers_[index] = true; - if (enqueued_index) { *enqueued_index = index; } From eadafff6aeee592ba373c1465f5d8feac3ef9d48 Mon Sep 17 00:00:00 2001 From: Eric Jeong Date: Tue, 1 Aug 2017 19:40:03 +0900 Subject: [PATCH 09/50] Close acquire fence fd after camera capture Camera capture should close acquire fence. If not, fd remains unused, which consumes all available fd resources for a process (usually 1024). Bug: 64214375 Test: Running camera preview of camera sample app for a long time should not break preview image. Exempt-From-Owner-Approval: This is a cherry-pick CL from oc-iot-dev. Change-Id: I91d6d3a7b7a95ed5b33c7c73bc85d42f69f4c856 (cherry picked from commit da3c52413a7499a3cd91246b0634f839315ed7b7) --- modules/camera/3_4/camera.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp index 7f42eef6..0f9e3784 100644 --- a/modules/camera/3_4/camera.cpp +++ b/modules/camera/3_4/camera.cpp @@ -455,6 +455,7 @@ int Camera::preprocessCaptureBuffer(camera3_stream_buffer_t *buffer) __func__, mId, strerror(-res), res); return res; } + ::close(buffer->acquire_fence); } // Acquire fence has been waited upon. From 424744cc4d9ef8daa624ed6a3687cb9ebf4c9b7e Mon Sep 17 00:00:00 2001 From: Jaesung Chung Date: Thu, 9 Nov 2017 12:51:32 +0900 Subject: [PATCH 10/50] Use RGB24 format instead of BGR32 BGR32 mode is in RPi3's camera has a RB color swapping issue. This CL makes to use stable RGB24 mode instead to avoid the problem without causing any quality regression. Bug: 69075512 Test: RB color swapping problem is gone on preview, recording and stil. Exempt-From-Owner-Approval: HAL is owned by Things team. Change-Id: I109363c0f68cec45f92e739a978f554e70032151 --- modules/camera/3_4/README.md | 5 +---- modules/camera/3_4/stream_format.cpp | 6 +++--- modules/camera/3_4/v4l2_gralloc.cpp | 14 ++++++++++++++ 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/modules/camera/3_4/README.md b/modules/camera/3_4/README.md index 73d0c13b..30f36d7d 100644 --- a/modules/camera/3_4/README.md +++ b/modules/camera/3_4/README.md @@ -28,7 +28,7 @@ to load the V4L2 HAL instead of a default Camera HAL. Devices and cameras wishing to use this HAL must meet the following requirements: -* The camera must support BGR32, YUV420, and JPEG formats. +* The camera must support RGB24, YUV420, and JPEG formats. * The gralloc and other graphics modules used by the device must use `HAL_PIXEL_FORMAT_RGBA_8888` as the `HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED` @@ -146,6 +146,3 @@ is underfeatured compared to the ideal/what is possible. * A variety of features are unimplemented: High speed capture, flash torch mode, hotplugging/unplugging. -* The HAL uses BGR for RGBA. Again, the HAL was designed for the Raspberry Pi -camera, which doesn't support RGB, but RGB is a common default format for -graphics stacks. diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp index c85c26be..70900abb 100644 --- a/modules/camera/3_4/stream_format.cpp +++ b/modules/camera/3_4/stream_format.cpp @@ -57,7 +57,7 @@ FormatCategory StreamFormat::Category() const { case V4L2_PIX_FMT_JPEG: return kFormatCategoryStalling; case V4L2_PIX_FMT_YUV420: // Fall through. - case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB24: return kFormatCategoryNonStalling; default: // Note: currently no supported RAW formats. @@ -87,7 +87,7 @@ int StreamFormat::V4L2ToHalPixelFormat(uint32_t v4l2_pixel_format) { case V4L2_PIX_FMT_YUV420: hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888; break; - case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB24: hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888; break; default: @@ -106,7 +106,7 @@ uint32_t StreamFormat::HalToV4L2PixelFormat(int hal_pixel_format) { case HAL_PIXEL_FORMAT_RGBA_8888: // Should be RGB32, but RPi doesn't support that. // For now we accept that the colors will be off. - v4l2_pixel_format = V4L2_PIX_FMT_BGR32; + v4l2_pixel_format = V4L2_PIX_FMT_RGB24; break; case HAL_PIXEL_FORMAT_YCbCr_420_888: v4l2_pixel_format = V4L2_PIX_FMT_YUV420; diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp index 7da3c4e2..2fcef355 100644 --- a/modules/camera/3_4/v4l2_gralloc.cpp +++ b/modules/camera/3_4/v4l2_gralloc.cpp @@ -146,6 +146,7 @@ int V4L2Gralloc::lock(const camera3_stream_buffer_t* camera_buffer, return ret; } break; + case V4L2_PIX_FMT_RGB24: // Fall-through. case V4L2_PIX_FMT_BGR32: // Fall-through. case V4L2_PIX_FMT_RGB32: // RGB formats have nice agreed upon representation. Unless using android @@ -204,6 +205,19 @@ int V4L2Gralloc::unlock(const v4l2_buffer* device_buffer) { const camera3_stream_buffer_t* camera_buffer = buffer_data->camera_buffer; const buffer_handle_t buffer = *camera_buffer->buffer; + if (StreamFormat::HalToV4L2PixelFormat(camera_buffer->stream->format) == V4L2_PIX_FMT_RGB24) { + // Convert RGB24 to RGB32. + size_t rgb_size = camera_buffer->stream->width * camera_buffer->stream->height; + uint8_t* tail_rgb24 = (uint8_t*)data + 3 * rgb_size - 1; + uint8_t* tail_rgb32 = (uint8_t*)data + 4 * rgb_size - 1; + for (int i = 0; i < rgb_size; i++) { + *(tail_rgb32--) = 0xff; + *(tail_rgb32--) = *(tail_rgb24--); + *(tail_rgb32--) = *(tail_rgb24--); + *(tail_rgb32--) = *(tail_rgb24--); + } + } + // Check for transform. if (buffer_data->transform_dest) { HAL_LOGV("Transforming V4L2 YUV to gralloc YUV."); From 6e8afead53ac1522247e979775674e2bdc6e7779 Mon Sep 17 00:00:00 2001 From: Jaesung Chung Date: Wed, 15 Nov 2017 09:30:41 +0900 Subject: [PATCH 11/50] Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED during setuping streams This CL makes the hack(ag/3176281) in frameworks/av not needed no longer. Bug: 69321320 Test: After reverting the hack in av, the camera sample app works. Exempt-From-Owner-Approval: HAL is owned by Things team. Change-Id: I510531bed401fe4fa6071fc151a1f75307a5decb --- modules/camera/3_4/v4l2_camera.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp index 2bc0c9f4..22406c92 100644 --- a/modules/camera/3_4/v4l2_camera.cpp +++ b/modules/camera/3_4/v4l2_camera.cpp @@ -413,6 +413,11 @@ int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) { for (uint32_t i = 0; i < stream_config->num_streams; ++i) { stream = stream_config->streams[i]; + // Override HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED format. + if (stream->format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { + stream->format = HAL_PIXEL_FORMAT_RGBA_8888; + } + // Max buffers as reported by the device. stream->max_buffers = max_buffers; From 9880f12e1990639dc5ccfe4e36131b39d30ebf58 Mon Sep 17 00:00:00 2001 From: Paul McLean Date: Tue, 28 Nov 2017 15:16:09 -0700 Subject: [PATCH 12/50] Removing unused and misleading constant. Test: None needed. Change-Id: I1fa020f38f488b0cf5196284f29220c3e6c1acd0 --- modules/usbaudio/audio_hal.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 43d1daf7..45601dfa 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -44,8 +44,6 @@ #include "alsa_device_proxy.h" #include "alsa_logging.h" -#define DEFAULT_INPUT_BUFFER_SIZE_MS 20 - /* Lock play & record samples rates at or above this threshold */ #define RATELOCK_THRESHOLD 96000 From 96c4d3035a94dbdc94f156989e22cddd495eeb51 Mon Sep 17 00:00:00 2001 From: Paul McLean Date: Tue, 5 Dec 2017 09:50:26 -0800 Subject: [PATCH 13/50] Remove unused variables/labels to eliminate compile warnings. Test: built and run on Marlin and testing with various USB peripherals. Bug:70180519 Change-Id: I68d7d33ffff8983117508e02a76d62c71d708c76 --- modules/usbaudio/audio_hal.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/modules/usbaudio/audio_hal.c b/modules/usbaudio/audio_hal.c index 43d1daf7..ef8bb034 100644 --- a/modules/usbaudio/audio_hal.c +++ b/modules/usbaudio/audio_hal.c @@ -375,7 +375,6 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) struct stream_out *out = (struct stream_out *)stream; - int routing = 0; int ret_value = 0; int card = -1; int device = -1; @@ -653,7 +652,9 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, 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. */ + /* TODO The retry mechanism isn't implemented in AudioPolicyManager/AudioFlinger + * So clear any errors that may have occurred above. + */ ret = 0; out->conversion_buffer = NULL; @@ -667,11 +668,6 @@ static int adev_open_output_stream(struct audio_hw_device *hw_dev, *stream_out = &out->stream; return ret; - -err_open: - free(out); - *stream_out = NULL; - return -ENOSYS; } static void adev_close_output_stream(struct audio_hw_device *hw_dev, @@ -783,9 +779,6 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs) struct stream_in *in = (struct stream_in *)stream; - char value[32]; - int param_val; - int routing = 0; int ret_value = 0; int card = -1; int device = -1; @@ -880,8 +873,6 @@ static ssize_t in_read(struct audio_stream_in *stream, void* buffer, size_t byte in->standby = false; } - const alsa_device_profile *profile = in->profile; - /* * OK, we need to figure out how much data to read to be able to output the requested * number of bytes in the HAL format (16-bit, stereo). @@ -1246,7 +1237,6 @@ static int adev_dump(const struct audio_hw_device *device, int fd) static int adev_close(hw_device_t *device) { - struct audio_device *adev = (struct audio_device *)device; free(device); return 0; From eec2ee9633339510255c914057ff59ac27b38b25 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Wed, 8 Nov 2017 19:33:27 +0000 Subject: [PATCH 14/50] camera: Bump device version to 3.5 This version update adds support for session keys and session parameters. Bug: 64450664 Test: Camera CTS Change-Id: Id14dbde5083c974b86b942dfd6e904dbe85e0ee5 --- include/hardware/camera3.h | 28 ++++++++++++++++++++++++++-- include/hardware/camera_common.h | 5 +++-- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index cec2ab3c..11e24910 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -21,7 +21,7 @@ #include "camera_common.h" /** - * Camera device HAL 3.4 [ CAMERA_DEVICE_API_VERSION_3_4 ] + * Camera device HAL 3.5[ CAMERA_DEVICE_API_VERSION_3_5 ] * * This is the current recommended version of the camera device HAL. * @@ -29,7 +29,7 @@ * android.hardware.camera2 API as LIMITED or above hardware level. * * Camera devices that support this version of the HAL must return - * CAMERA_DEVICE_API_VERSION_3_4 in camera_device_t.common.version and in + * CAMERA_DEVICE_API_VERSION_3_5 in camera_device_t.common.version and in * camera_info_t.device_version (from camera_module_t.get_camera_info). * * CAMERA_DEVICE_API_VERSION_3_3 and above: @@ -157,6 +157,18 @@ * - ANDROID_SENSOR_DYNAMIC_WHITE_LEVEL * - ANDROID_SENSOR_OPAQUE_RAW_SIZE * - ANDROID_SENSOR_OPTICAL_BLACK_REGIONS + * + * 3.5: Minor additions to supported metadata and changes to camera3_stream_configuration. + * + * - Add ANDROID_REQUEST_AVAILABLE_SESSION_KEYS static metadata, which is + * optional for implementations that want to support session parameters. If support is + * needed, then Hal should populate the list with all available capture request keys + * that can cause severe processing delays when modified by client. Typical examples + * include parameters that require time-consuming HW re-configuration or internal camera + * pipeline update. + * + * - Add a session parameter field to camera3_stream_configuration which can be populated + * by clients with initial values for the keys found in ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. */ /** @@ -1734,6 +1746,18 @@ typedef struct camera3_stream_configuration { * */ uint32_t operation_mode; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_5: + * + * The session metadata buffer contains the initial values of + * ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. This field is optional + * and camera clients can choose to ignore it, in which case it will + * be set to NULL. If parameters are present, then Hal should examine + * the parameter values and configure its internal camera pipeline + * accordingly. + */ + const camera_metadata_t *session_parameters; } camera3_stream_configuration_t; /** diff --git a/include/hardware/camera_common.h b/include/hardware/camera_common.h index 7bafa88f..edd1ada3 100644 --- a/include/hardware/camera_common.h +++ b/include/hardware/camera_common.h @@ -148,10 +148,11 @@ __BEGIN_DECLS #define CAMERA_DEVICE_API_VERSION_3_2 HARDWARE_DEVICE_API_VERSION(3, 2) #define CAMERA_DEVICE_API_VERSION_3_3 HARDWARE_DEVICE_API_VERSION(3, 3) #define CAMERA_DEVICE_API_VERSION_3_4 HARDWARE_DEVICE_API_VERSION(3, 4) +#define CAMERA_DEVICE_API_VERSION_3_5 HARDWARE_DEVICE_API_VERSION(3, 5) -// Device version 3.4 is current, older HAL camera device versions are not +// Device version 3.5 is current, older HAL camera device versions are not // recommended for new devices. -#define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_4 +#define CAMERA_DEVICE_API_VERSION_CURRENT CAMERA_DEVICE_API_VERSION_3_5 /** * Defined in /system/media/camera/include/system/camera_metadata.h From 932d4dddd97ca2c690363a2245cfab46dab6496f Mon Sep 17 00:00:00 2001 From: Jaesung Chung Date: Fri, 15 Dec 2017 15:27:21 +0900 Subject: [PATCH 15/50] Support native camera resolutions This CL makes camera HAL support native camera resoultions up to 3280x2464, which is the maximum camera resolution of RPi3's camera module version two. Bug: 69983703 Test: Verified with ThingsCameraQA.apk Exempt-From-Owner-Approval: V4L2 camera HAL is owned by iot team. Change-Id: I303e763e87bdfc5ae81d398aac8be0730e57b05d --- modules/camera/3_4/v4l2_metadata_factory.cpp | 2 +- modules/camera/3_4/v4l2_wrapper.cpp | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/modules/camera/3_4/v4l2_metadata_factory.cpp b/modules/camera/3_4/v4l2_metadata_factory.cpp index 67556d9e..3d9cfbb0 100644 --- a/modules/camera/3_4/v4l2_metadata_factory.cpp +++ b/modules/camera/3_4/v4l2_metadata_factory.cpp @@ -476,7 +476,7 @@ int GetV4L2Metadata(std::shared_ptr device, new Property(ANDROID_SCALER_CROPPING_TYPE, ANDROID_SCALER_CROPPING_TYPE_FREEFORM))); // Spoof pixel array size for now, eventually get from CROPCAP. - std::array pixel_array_size = {{640, 480}}; + std::array pixel_array_size = {{3280, 2464}}; components.insert(std::unique_ptr( new Property>(ANDROID_SENSOR_INFO_PIXEL_ARRAY_SIZE, pixel_array_size))); diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp index b5a1c71a..36d04116 100644 --- a/modules/camera/3_4/v4l2_wrapper.cpp +++ b/modules/camera/3_4/v4l2_wrapper.cpp @@ -35,7 +35,19 @@ namespace v4l2_camera_hal { -const int32_t kStandardSizes[][2] = {{640, 480}, {320, 240}}; +const int32_t kStandardSizes[][2] = { + {4096, 2160}, // 4KDCI (for USB camera) + {3840, 2160}, // 4KUHD (for USB camera) + {3280, 2464}, // 8MP + {2560, 1440}, // QHD + {1920, 1080}, // HD1080 + {1640, 1232}, // 2MP + {1280, 720}, // HD + {1024, 768}, // XGA + { 640, 480}, // VGA + { 320, 240}, // QVGA + { 176, 144} // QCIF +}; V4L2Wrapper* V4L2Wrapper::NewV4L2Wrapper(const std::string device_path) { std::unique_ptr gralloc(V4L2Gralloc::NewV4L2Gralloc()); @@ -364,7 +376,7 @@ int V4L2Wrapper::GetFormatFrameSizes(uint32_t v4l2_format, desired_height, v4l2_format); continue; - } else if (desired_width > size_query.stepwise.max_width && + } else if (desired_width > size_query.stepwise.max_width || desired_height > size_query.stepwise.max_height) { HAL_LOGV("Standard size %u x %u is too big for format %d", desired_width, From 28e0f76353e06b24b7dae54e636dbb5ddc64d1a5 Mon Sep 17 00:00:00 2001 From: Prashanth Swaminathan Date: Thu, 27 Apr 2017 11:32:11 -0700 Subject: [PATCH 16/50] v4l2 camera: port ARC++ image processing code Utiltizes ARC++ image processing code to perform the conversion between the camera format and the requested format from the framework. In order to support USB devices which may not implement the required formats, conversion between YUYV/MJPEG to the request format is done on-the-fly. TEST: All existing unit tests pass. Tested manually with the camera sample APK, preview/video/capture in both JPEG and YUV formats. Tested on the RPi v2 Camera, the Logitech C270 and the 180 degree Fisheye USB camera. Bug: 37708856, Bug: 69983918 Exempt-From-Owner-Approval: This HAL is owned by AT team. Change-Id: I1a54581d1170fa3270036ec366fb613fe587a094 --- modules/camera/3_4/Android.mk | 17 +- modules/camera/3_4/README.md | 2 +- modules/camera/3_4/arc/cached_frame.cpp | 218 ++++++++ modules/camera/3_4/arc/cached_frame.h | 86 +++ modules/camera/3_4/arc/common.h | 28 + modules/camera/3_4/arc/common_types.h | 55 ++ modules/camera/3_4/arc/exif_utils.cpp | 513 ++++++++++++++++++ modules/camera/3_4/arc/exif_utils.h | 178 ++++++ modules/camera/3_4/arc/frame_buffer.cpp | 188 +++++++ modules/camera/3_4/arc/frame_buffer.h | 135 +++++ modules/camera/3_4/arc/image_processor.cpp | 491 +++++++++++++++++ modules/camera/3_4/arc/image_processor.h | 48 ++ modules/camera/3_4/arc/jpeg_compressor.cpp | 190 +++++++ modules/camera/3_4/arc/jpeg_compressor.h | 74 +++ .../camera/3_4/format_metadata_factory.cpp | 153 ++++-- modules/camera/3_4/format_metadata_factory.h | 1 + .../3_4/format_metadata_factory_test.cpp | 111 ++-- modules/camera/3_4/metadata/control_test.cpp | 12 +- .../partial_metadata_factory_test.cpp | 18 +- modules/camera/3_4/metadata/property_test.cpp | 14 +- modules/camera/3_4/metadata/state_test.cpp | 4 +- modules/camera/3_4/metadata/test_common.h | 6 +- modules/camera/3_4/stream_format.cpp | 151 +++++- modules/camera/3_4/stream_format.h | 17 + modules/camera/3_4/v4l2_camera.cpp | 78 +-- modules/camera/3_4/v4l2_camera.h | 4 +- modules/camera/3_4/v4l2_gralloc.cpp | 348 ------------ modules/camera/3_4/v4l2_gralloc.h | 71 --- modules/camera/3_4/v4l2_metadata_factory.cpp | 8 +- modules/camera/3_4/v4l2_wrapper.cpp | 237 +++++--- modules/camera/3_4/v4l2_wrapper.h | 49 +- modules/camera/3_4/v4l2_wrapper_mock.h | 10 +- 32 files changed, 2798 insertions(+), 717 deletions(-) create mode 100644 modules/camera/3_4/arc/cached_frame.cpp create mode 100644 modules/camera/3_4/arc/cached_frame.h create mode 100644 modules/camera/3_4/arc/common.h create mode 100644 modules/camera/3_4/arc/common_types.h create mode 100644 modules/camera/3_4/arc/exif_utils.cpp create mode 100644 modules/camera/3_4/arc/exif_utils.h create mode 100644 modules/camera/3_4/arc/frame_buffer.cpp create mode 100644 modules/camera/3_4/arc/frame_buffer.h create mode 100644 modules/camera/3_4/arc/image_processor.cpp create mode 100644 modules/camera/3_4/arc/image_processor.h create mode 100644 modules/camera/3_4/arc/jpeg_compressor.cpp create mode 100644 modules/camera/3_4/arc/jpeg_compressor.h delete mode 100644 modules/camera/3_4/v4l2_gralloc.cpp delete mode 100644 modules/camera/3_4/v4l2_gralloc.h diff --git a/modules/camera/3_4/Android.mk b/modules/camera/3_4/Android.mk index 05ddf5a9..6ecedaca 100644 --- a/modules/camera/3_4/Android.mk +++ b/modules/camera/3_4/Android.mk @@ -22,21 +22,31 @@ ifeq ($(USE_CAMERA_V4L2_HAL), true) v4l2_shared_libs := \ libbase \ + libchrome \ libcamera_client \ libcamera_metadata \ libcutils \ + libexif \ libhardware \ liblog \ libsync \ libutils \ -v4l2_static_libs := +v4l2_static_libs := \ + libyuv_static \ + libjpeg_static_ndk \ -v4l2_cflags := -fno-short-enums -Wall -Wno-error -Wextra -fvisibility=hidden +v4l2_cflags := -fno-short-enums -Wall -Wno-error -Wextra -fvisibility=hidden -DHAVE_JPEG -v4l2_c_includes := $(call include-path-for, camera) +v4l2_c_includes := $(call include-path-for, camera) \ + external/libyuv/files/include \ v4l2_src_files := \ + arc/cached_frame.cpp \ + arc/exif_utils.cpp \ + arc/frame_buffer.cpp \ + arc/image_processor.cpp \ + arc/jpeg_compressor.cpp \ camera.cpp \ capture_request.cpp \ format_metadata_factory.cpp \ @@ -49,7 +59,6 @@ v4l2_src_files := \ stream_format.cpp \ v4l2_camera.cpp \ v4l2_camera_hal.cpp \ - v4l2_gralloc.cpp \ v4l2_metadata_factory.cpp \ v4l2_wrapper.cpp \ diff --git a/modules/camera/3_4/README.md b/modules/camera/3_4/README.md index 30f36d7d..168ba97f 100644 --- a/modules/camera/3_4/README.md +++ b/modules/camera/3_4/README.md @@ -28,7 +28,7 @@ to load the V4L2 HAL instead of a default Camera HAL. Devices and cameras wishing to use this HAL must meet the following requirements: -* The camera must support RGB24, YUV420, and JPEG formats. +* The camera must support BGR32, YUV420, and JPEG formats. * The gralloc and other graphics modules used by the device must use `HAL_PIXEL_FORMAT_RGBA_8888` as the `HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED` diff --git a/modules/camera/3_4/arc/cached_frame.cpp b/modules/camera/3_4/arc/cached_frame.cpp new file mode 100644 index 00000000..0489be82 --- /dev/null +++ b/modules/camera/3_4/arc/cached_frame.cpp @@ -0,0 +1,218 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "arc/cached_frame.h" + +#include +#include + +#include "arc/common.h" +#include "arc/common_types.h" + +namespace arc { + +using android::CameraMetadata; + +CachedFrame::CachedFrame() + : source_frame_(nullptr), + cropped_buffer_capacity_(0), + yu12_frame_(new AllocatedFrameBuffer(0)) {} + +CachedFrame::~CachedFrame() { UnsetSource(); } + +int CachedFrame::SetSource(const FrameBuffer* frame, int rotate_degree) { + source_frame_ = frame; + int res = ConvertToYU12(); + if (res != 0) { + return res; + } + + if (rotate_degree > 0) { + res = CropRotateScale(rotate_degree); + } + return res; +} + +void CachedFrame::UnsetSource() { source_frame_ = nullptr; } + +uint8_t* CachedFrame::GetSourceBuffer() const { + return source_frame_->GetData(); +} + +size_t CachedFrame::GetSourceDataSize() const { + return source_frame_->GetDataSize(); +} + +uint32_t CachedFrame::GetSourceFourCC() const { + return source_frame_->GetFourcc(); +} + +uint8_t* CachedFrame::GetCachedBuffer() const { return yu12_frame_->GetData(); } + +uint32_t CachedFrame::GetCachedFourCC() const { + return yu12_frame_->GetFourcc(); +} + +uint32_t CachedFrame::GetWidth() const { return yu12_frame_->GetWidth(); } + +uint32_t CachedFrame::GetHeight() const { return yu12_frame_->GetHeight(); } + +size_t CachedFrame::GetConvertedSize(int fourcc) const { + return ImageProcessor::GetConvertedSize(fourcc, yu12_frame_->GetWidth(), + yu12_frame_->GetHeight()); +} + +int CachedFrame::Convert(const CameraMetadata& metadata, FrameBuffer* out_frame, + bool video_hack) { + if (video_hack && out_frame->GetFourcc() == V4L2_PIX_FMT_YVU420) { + out_frame->SetFourcc(V4L2_PIX_FMT_YUV420); + } + + FrameBuffer* source_frame = yu12_frame_.get(); + if (GetWidth() != out_frame->GetWidth() || + GetHeight() != out_frame->GetHeight()) { + size_t cache_size = ImageProcessor::GetConvertedSize( + yu12_frame_->GetFourcc(), out_frame->GetWidth(), + out_frame->GetHeight()); + if (cache_size == 0) { + return -EINVAL; + } else if (cache_size > scaled_frame_->GetBufferSize()) { + scaled_frame_.reset(new AllocatedFrameBuffer(cache_size)); + } + scaled_frame_->SetWidth(out_frame->GetWidth()); + scaled_frame_->SetHeight(out_frame->GetHeight()); + ImageProcessor::Scale(*yu12_frame_.get(), scaled_frame_.get()); + + source_frame = scaled_frame_.get(); + } + return ImageProcessor::ConvertFormat(metadata, *source_frame, out_frame); +} + +int CachedFrame::ConvertToYU12() { + size_t cache_size = ImageProcessor::GetConvertedSize( + V4L2_PIX_FMT_YUV420, source_frame_->GetWidth(), + source_frame_->GetHeight()); + if (cache_size == 0) { + return -EINVAL; + } + yu12_frame_->SetDataSize(cache_size); + yu12_frame_->SetFourcc(V4L2_PIX_FMT_YUV420); + yu12_frame_->SetWidth(source_frame_->GetWidth()); + yu12_frame_->SetHeight(source_frame_->GetHeight()); + + int res = ImageProcessor::ConvertFormat(CameraMetadata(), *source_frame_, + yu12_frame_.get()); + if (res) { + LOGF(ERROR) << "Convert from " << FormatToString(source_frame_->GetFourcc()) + << " to YU12 fails."; + return res; + } + return 0; +} + +int CachedFrame::CropRotateScale(int rotate_degree) { + // TODO(henryhsu): Move libyuv part to ImageProcessor. + if (yu12_frame_->GetHeight() % 2 != 0 || yu12_frame_->GetWidth() % 2 != 0) { + LOGF(ERROR) << "yu12_frame_ has odd dimension: " << yu12_frame_->GetWidth() + << "x" << yu12_frame_->GetHeight(); + return -EINVAL; + } + + if (yu12_frame_->GetHeight() > yu12_frame_->GetWidth()) { + LOGF(ERROR) << "yu12_frame_ is tall frame already: " + << yu12_frame_->GetWidth() << "x" << yu12_frame_->GetHeight(); + return -EINVAL; + } + + // Step 1: Crop and rotate + // + // Original frame Cropped frame Rotated frame + // -------------------- -------- + // | | | | | | --------------- + // | | | | | | | | + // | | | | =======>> | | =======>> | | + // | | | | | | --------------- + // | | | | | | + // -------------------- -------- + // + int cropped_width = yu12_frame_->GetHeight() * yu12_frame_->GetHeight() / + yu12_frame_->GetWidth(); + if (cropped_width % 2 == 1) { + // Make cropped_width to the closest even number. + cropped_width++; + } + int cropped_height = yu12_frame_->GetHeight(); + int margin = (yu12_frame_->GetWidth() - cropped_width) / 2; + + int rotated_height = cropped_width; + int rotated_width = cropped_height; + + int rotated_y_stride = rotated_width; + int rotated_uv_stride = rotated_width / 2; + size_t rotated_size = + rotated_y_stride * rotated_height + rotated_uv_stride * rotated_height; + if (rotated_size > cropped_buffer_capacity_) { + cropped_buffer_.reset(new uint8_t[rotated_size]); + cropped_buffer_capacity_ = rotated_size; + } + uint8_t* rotated_y_plane = cropped_buffer_.get(); + uint8_t* rotated_u_plane = + rotated_y_plane + rotated_y_stride * rotated_height; + uint8_t* rotated_v_plane = + rotated_u_plane + rotated_uv_stride * rotated_height / 2; + libyuv::RotationMode rotation_mode = libyuv::RotationMode::kRotate90; + switch (rotate_degree) { + case 90: + rotation_mode = libyuv::RotationMode::kRotate90; + break; + case 270: + rotation_mode = libyuv::RotationMode::kRotate270; + break; + default: + LOGF(ERROR) << "Invalid rotation degree: " << rotate_degree; + return -EINVAL; + } + // This libyuv method first crops the frame and then rotates it 90 degrees + // clockwise. + int res = libyuv::ConvertToI420( + yu12_frame_->GetData(), yu12_frame_->GetDataSize(), rotated_y_plane, + rotated_y_stride, rotated_u_plane, rotated_uv_stride, rotated_v_plane, + rotated_uv_stride, margin, 0, yu12_frame_->GetWidth(), + yu12_frame_->GetHeight(), cropped_width, cropped_height, rotation_mode, + libyuv::FourCC::FOURCC_I420); + + if (res) { + LOGF(ERROR) << "ConvertToI420 failed: " << res; + return res; + } + + // Step 2: Scale + // + // Final frame + // Rotated frame --------------------- + // -------------- | | + // | | =====>> | | + // | | | | + // -------------- | | + // | | + // --------------------- + // + // + res = libyuv::I420Scale( + rotated_y_plane, rotated_y_stride, rotated_u_plane, rotated_uv_stride, + rotated_v_plane, rotated_uv_stride, rotated_width, rotated_height, + yu12_frame_->GetData(), yu12_frame_->GetWidth(), + yu12_frame_->GetData() + + yu12_frame_->GetWidth() * yu12_frame_->GetHeight(), + yu12_frame_->GetWidth() / 2, + yu12_frame_->GetData() + + yu12_frame_->GetWidth() * yu12_frame_->GetHeight() * 5 / 4, + yu12_frame_->GetWidth() / 2, yu12_frame_->GetWidth(), + yu12_frame_->GetHeight(), libyuv::FilterMode::kFilterNone); + LOGF_IF(ERROR, res) << "I420Scale failed: " << res; + return res; +} + +} // namespace arc diff --git a/modules/camera/3_4/arc/cached_frame.h b/modules/camera/3_4/arc/cached_frame.h new file mode 100644 index 00000000..fbfcb76b --- /dev/null +++ b/modules/camera/3_4/arc/cached_frame.h @@ -0,0 +1,86 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef HAL_USB_CACHED_FRAME_H_ +#define HAL_USB_CACHED_FRAME_H_ + +#include + +#include + +#include "arc/image_processor.h" + +namespace arc { + +// CachedFrame contains a source FrameBuffer and a cached, converted +// FrameBuffer. The incoming frames would be converted to YU12, the default +// format of libyuv, to allow convenient processing. +class CachedFrame { + public: + CachedFrame(); + ~CachedFrame(); + + // SetSource() doesn't take ownership of |frame|. The caller can only release + // |frame| after calling UnsetSource(). SetSource() immediately converts + // incoming frame into YU12. Return non-zero values if it encounters errors. + // If |rotate_degree| is 90 or 270, |frame| will be cropped, rotated by the + // specified amount and scaled. + // If |rotate_degree| is -1, |frame| will not be cropped, rotated, and scaled. + // This function will return an error if |rotate_degree| is not -1, 90, or + // 270. + int SetSource(const FrameBuffer* frame, int rotate_degree); + void UnsetSource(); + + uint8_t* GetSourceBuffer() const; + size_t GetSourceDataSize() const; + uint32_t GetSourceFourCC() const; + uint8_t* GetCachedBuffer() const; + uint32_t GetCachedFourCC() const; + + uint32_t GetWidth() const; + uint32_t GetHeight() const; + + // Calculate the output buffer size when converting to the specified pixel + // format. |fourcc| is defined as V4L2_PIX_FMT_* in linux/videodev2.h. Return + // 0 on error. + size_t GetConvertedSize(int fourcc) const; + + // Caller should fill everything except |data_size| and |fd| of |out_frame|. + // The function will do format conversion and scale to fit |out_frame| + // requirement. + // If |video_hack| is true, it outputs YU12 when |hal_pixel_format| is YV12 + // (swapping U/V planes). Caller should fill |fourcc|, |data|, and + // Return non-zero error code on failure; return 0 on success. + int Convert(const android::CameraMetadata& metadata, FrameBuffer* out_frame, + bool video_hack = false); + + private: + int ConvertToYU12(); + // When we have a landscape mounted camera and the current camera activity is + // portrait, the frames shown in the activity would be stretched. Therefore, + // we want to simulate a native portrait camera. That's why we want to crop, + // rotate |rotate_degree| clockwise and scale the frame. HAL would not change + // CameraInfo.orientation. Instead, framework would fake the + // CameraInfo.orientation. Framework would then tell HAL how much the frame + // needs to rotate clockwise by |rotate_degree|. + int CropRotateScale(int rotate_degree); + + const FrameBuffer* source_frame_; + // const V4L2FrameBuffer* source_frame_; + + // Temporary buffer for cropped and rotated results. + std::unique_ptr cropped_buffer_; + size_t cropped_buffer_capacity_; + + // Cache YU12 decoded results. + std::unique_ptr yu12_frame_; + + // Temporary buffer for scaled results. + std::unique_ptr scaled_frame_; +}; + +} // namespace arc + +#endif // HAL_USB_CACHED_FRAME_H_ diff --git a/modules/camera/3_4/arc/common.h b/modules/camera/3_4/arc/common.h new file mode 100644 index 00000000..25e4eb58 --- /dev/null +++ b/modules/camera/3_4/arc/common.h @@ -0,0 +1,28 @@ +/* Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef INCLUDE_ARC_COMMON_H_ +#define INCLUDE_ARC_COMMON_H_ + +#include + +#include + +#define LOGF(level) LOG(level) << __FUNCTION__ << "(): " +#define LOGFID(level, id) LOG(level) << __FUNCTION__ << "(): id: " << id << ": " +#define LOGF_IF(level, res) LOG_IF(level, res) << __FUNCTION__ << "(): " + +#define VLOGF(level) VLOG(level) << __FUNCTION__ << "(): " +#define VLOGFID(level, id) \ + VLOG(level) << __FUNCTION__ << "(): id: " << id << ": " + +#define VLOGF_ENTER() VLOGF(1) << "enter" +#define VLOGF_EXIT() VLOGF(1) << "exit" + +inline std::string FormatToString(int32_t format) { + return std::string(reinterpret_cast(&format), 4); +} + +#endif // INCLUDE_ARC_COMMON_H_ diff --git a/modules/camera/3_4/arc/common_types.h b/modules/camera/3_4/arc/common_types.h new file mode 100644 index 00000000..8f62ad6e --- /dev/null +++ b/modules/camera/3_4/arc/common_types.h @@ -0,0 +1,55 @@ +/* + * Copyright 2016 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef HAL_USB_COMMON_TYPES_H_ +#define HAL_USB_COMMON_TYPES_H_ + +#include +#include + +namespace arc { + +struct DeviceInfo { + // ex: /dev/video0 + std::string device_path; + // USB vender id + std::string usb_vid; + // USB product id + std::string usb_pid; + // Some cameras need to wait several frames to output correct images. + uint32_t frames_to_skip_after_streamon; + + // Member definitions can be found in https://developer.android.com/ + // reference/android/hardware/camera2/CameraCharacteristics.html + uint32_t lens_facing; + int32_t sensor_orientation; + float horizontal_view_angle_16_9; + float horizontal_view_angle_4_3; + std::vector lens_info_available_focal_lengths; + float lens_info_minimum_focus_distance; + float lens_info_optimal_focus_distance; + float vertical_view_angle_16_9; + float vertical_view_angle_4_3; +}; + +typedef std::vector DeviceInfos; + +struct SupportedFormat { + uint32_t width; + uint32_t height; + uint32_t fourcc; + // All the supported frame rates in fps with given width, height, and + // pixelformat. This is not sorted. For example, suppose width, height, and + // fourcc are 640x480 YUYV. If frameRates are 15.0 and 30.0, the camera + // supports outputting 640X480 YUYV in 15fps or 30fps. + std::vector frameRates; +}; + +typedef std::vector SupportedFormats; + +} // namespace arc + +#endif // HAL_USB_COMMON_TYPES_H_ diff --git a/modules/camera/3_4/arc/exif_utils.cpp b/modules/camera/3_4/arc/exif_utils.cpp new file mode 100644 index 00000000..aec53c54 --- /dev/null +++ b/modules/camera/3_4/arc/exif_utils.cpp @@ -0,0 +1,513 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "arc/exif_utils.h" + +#include +#include + +#include + +#include "arc/common.h" + +namespace std { + +template <> +struct default_delete { + inline void operator()(ExifEntry* entry) const { exif_entry_unref(entry); } +}; + +} // namespace std + +namespace arc { + +// This comes from the Exif Version 2.3 standard table 9. +const uint8_t gExifAsciiPrefix[] = {0x41, 0x53, 0x43, 0x49, + 0x49, 0x0, 0x0, 0x0}; + +static void SetLatitudeOrLongitudeData(unsigned char* data, double num) { + // Take the integer part of |num|. + ExifLong degrees = static_cast(num); + ExifLong minutes = static_cast(60 * (num - degrees)); + ExifLong microseconds = + static_cast(3600000000u * (num - degrees - minutes / 60.0)); + exif_set_rational(data, EXIF_BYTE_ORDER_INTEL, {degrees, 1}); + exif_set_rational(data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, + {minutes, 1}); + exif_set_rational(data + 2 * sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, + {microseconds, 1000000}); +} + +ExifUtils::ExifUtils() + : yu12_buffer_(nullptr), + yu12_width_(0), + yu12_height_(0), + thumbnail_width_(0), + thumbnail_height_(0), + exif_data_(nullptr), + app1_buffer_(nullptr), + app1_length_(0) {} + +ExifUtils::~ExifUtils() { Reset(); } + +bool ExifUtils::Initialize(const uint8_t* buffer, uint16_t width, + uint16_t height, int quality) { + Reset(); + + if (width % 2 != 0 || height % 2 != 0) { + LOGF(ERROR) << "invalid image size " << width << "x" << height; + return false; + } + if (quality < 1 || quality > 100) { + LOGF(ERROR) << "invalid jpeg quality " << quality; + return false; + } + thumbnail_jpeg_quality_ = quality; + yu12_buffer_ = buffer; + yu12_width_ = width; + yu12_height_ = height; + + exif_data_ = exif_data_new(); + if (exif_data_ == nullptr) { + LOGF(ERROR) << "allocate memory for exif_data_ failed"; + return false; + } + // Set the image options. + exif_data_set_option(exif_data_, EXIF_DATA_OPTION_FOLLOW_SPECIFICATION); + exif_data_set_data_type(exif_data_, EXIF_DATA_TYPE_COMPRESSED); + exif_data_set_byte_order(exif_data_, EXIF_BYTE_ORDER_INTEL); + + // Set image width and length. + SetImageWidth(width); + SetImageLength(height); + + return true; +} + +bool ExifUtils::SetMaker(const std::string& maker) { + size_t entrySize = maker.length() + 1; + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_0, EXIF_TAG_MAKE, EXIF_FORMAT_ASCII, entrySize, entrySize); + if (!entry) { + LOGF(ERROR) << "Adding Make exif entry failed"; + return false; + } + memcpy(entry->data, maker.c_str(), entrySize); + return true; +} + +bool ExifUtils::SetModel(const std::string& model) { + size_t entrySize = model.length() + 1; + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_0, EXIF_TAG_MODEL, EXIF_FORMAT_ASCII, entrySize, entrySize); + if (!entry) { + LOGF(ERROR) << "Adding Model exif entry failed"; + return false; + } + memcpy(entry->data, model.c_str(), entrySize); + return true; +} + +bool ExifUtils::SetDateTime(const struct tm& t) { + // The length is 20 bytes including NULL for termination in Exif standard. + char str[20]; + int result = snprintf(str, sizeof(str), "%04i:%02i:%02i %02i:%02i:%02i", + t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, t.tm_hour, + t.tm_min, t.tm_sec); + if (result != sizeof(str) - 1) { + LOGF(WARNING) << "Input time is invalid"; + return false; + } + std::unique_ptr entry = + AddVariableLengthEntry(EXIF_IFD_0, EXIF_TAG_DATE_TIME, EXIF_FORMAT_ASCII, + sizeof(str), sizeof(str)); + if (!entry) { + LOGF(ERROR) << "Adding DateTime exif entry failed"; + return false; + } + memcpy(entry->data, str, sizeof(str)); + return true; +} + +bool ExifUtils::SetFocalLength(uint32_t numerator, uint32_t denominator) { + std::unique_ptr entry = + AddEntry(EXIF_IFD_EXIF, EXIF_TAG_FOCAL_LENGTH); + if (!entry) { + LOGF(ERROR) << "Adding FocalLength exif entry failed"; + return false; + } + exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, + {numerator, denominator}); + return true; +} + +bool ExifUtils::SetGpsLatitude(double latitude) { + const ExifTag refTag = static_cast(EXIF_TAG_GPS_LATITUDE_REF); + std::unique_ptr refEntry = + AddVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2); + if (!refEntry) { + LOGF(ERROR) << "Adding GPSLatitudeRef exif entry failed"; + return false; + } + if (latitude >= 0) { + memcpy(refEntry->data, "N", sizeof("N")); + } else { + memcpy(refEntry->data, "S", sizeof("S")); + latitude *= -1; + } + + const ExifTag tag = static_cast(EXIF_TAG_GPS_LATITUDE); + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational)); + if (!entry) { + exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get()); + LOGF(ERROR) << "Adding GPSLatitude exif entry failed"; + return false; + } + SetLatitudeOrLongitudeData(entry->data, latitude); + + return true; +} + +bool ExifUtils::SetGpsLongitude(double longitude) { + ExifTag refTag = static_cast(EXIF_TAG_GPS_LONGITUDE_REF); + std::unique_ptr refEntry = + AddVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_ASCII, 2, 2); + if (!refEntry) { + LOGF(ERROR) << "Adding GPSLongitudeRef exif entry failed"; + return false; + } + if (longitude >= 0) { + memcpy(refEntry->data, "E", sizeof("E")); + } else { + memcpy(refEntry->data, "W", sizeof("W")); + longitude *= -1; + } + + ExifTag tag = static_cast(EXIF_TAG_GPS_LONGITUDE); + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 3, 3 * sizeof(ExifRational)); + if (!entry) { + exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get()); + LOGF(ERROR) << "Adding GPSLongitude exif entry failed"; + return false; + } + SetLatitudeOrLongitudeData(entry->data, longitude); + + return true; +} + +bool ExifUtils::SetGpsAltitude(double altitude) { + ExifTag refTag = static_cast(EXIF_TAG_GPS_ALTITUDE_REF); + std::unique_ptr refEntry = + AddVariableLengthEntry(EXIF_IFD_GPS, refTag, EXIF_FORMAT_BYTE, 1, 1); + if (!refEntry) { + LOGF(ERROR) << "Adding GPSAltitudeRef exif entry failed"; + return false; + } + if (altitude >= 0) { + *refEntry->data = 0; + } else { + *refEntry->data = 1; + altitude *= -1; + } + + ExifTag tag = static_cast(EXIF_TAG_GPS_ALTITUDE); + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_GPS, tag, EXIF_FORMAT_RATIONAL, 1, sizeof(ExifRational)); + if (!entry) { + exif_content_remove_entry(exif_data_->ifd[EXIF_IFD_GPS], refEntry.get()); + LOGF(ERROR) << "Adding GPSAltitude exif entry failed"; + return false; + } + exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, + {static_cast(altitude * 1000), 1000}); + + return true; +} + +bool ExifUtils::SetGpsTimestamp(const struct tm& t) { + const ExifTag dateTag = static_cast(EXIF_TAG_GPS_DATE_STAMP); + const size_t kGpsDateStampSize = 11; + std::unique_ptr entry = + AddVariableLengthEntry(EXIF_IFD_GPS, dateTag, EXIF_FORMAT_ASCII, + kGpsDateStampSize, kGpsDateStampSize); + if (!entry) { + LOGF(ERROR) << "Adding GPSDateStamp exif entry failed"; + return false; + } + int result = + snprintf(reinterpret_cast(entry->data), kGpsDateStampSize, + "%04i:%02i:%02i", t.tm_year + 1900, t.tm_mon + 1, t.tm_mday); + if (result != kGpsDateStampSize - 1) { + LOGF(WARNING) << "Input time is invalid"; + return false; + } + + const ExifTag timeTag = static_cast(EXIF_TAG_GPS_TIME_STAMP); + entry = AddVariableLengthEntry(EXIF_IFD_GPS, timeTag, EXIF_FORMAT_RATIONAL, 3, + 3 * sizeof(ExifRational)); + if (!entry) { + LOGF(ERROR) << "Adding GPSTimeStamp exif entry failed"; + return false; + } + exif_set_rational(entry->data, EXIF_BYTE_ORDER_INTEL, + {static_cast(t.tm_hour), 1}); + exif_set_rational(entry->data + sizeof(ExifRational), EXIF_BYTE_ORDER_INTEL, + {static_cast(t.tm_min), 1}); + exif_set_rational(entry->data + 2 * sizeof(ExifRational), + EXIF_BYTE_ORDER_INTEL, + {static_cast(t.tm_sec), 1}); + + return true; +} + +bool ExifUtils::SetGpsProcessingMethod(const std::string& method) { + ExifTag tag = static_cast(EXIF_TAG_GPS_PROCESSING_METHOD); + size_t size = sizeof(gExifAsciiPrefix) + method.length(); + std::unique_ptr entry = AddVariableLengthEntry( + EXIF_IFD_GPS, tag, EXIF_FORMAT_UNDEFINED, size, size); + if (!entry) { + LOGF(ERROR) << "Adding GPSProcessingMethod exif entry failed"; + return false; + } + memcpy(entry->data, gExifAsciiPrefix, sizeof(gExifAsciiPrefix)); + // Since the exif format is undefined, NULL termination is not necessary. + memcpy(entry->data + sizeof(gExifAsciiPrefix), method.c_str(), + method.length()); + + return true; +} + +bool ExifUtils::SetThumbnailSize(uint16_t width, uint16_t height) { + if (width % 2 != 0 || height % 2 != 0) { + LOGF(ERROR) << "Invalid thumbnail size " << width << "x" << height; + return false; + } + thumbnail_width_ = width; + thumbnail_height_ = height; + return true; +} + +bool ExifUtils::SetOrientation(uint16_t orientation) { + std::unique_ptr entry = AddEntry(EXIF_IFD_0, EXIF_TAG_ORIENTATION); + if (!entry) { + LOGF(ERROR) << "Adding Orientation exif entry failed"; + return false; + } + /* + * Orientation value: + * 1 2 3 4 5 6 7 8 + * + * 888888 888888 88 88 8888888888 88 88 8888888888 + * 88 88 88 88 88 88 88 88 88 88 88 88 + * 8888 8888 8888 8888 88 8888888888 8888888888 88 + * 88 88 88 88 + * 88 88 888888 888888 + */ + int value = 1; + switch (orientation) { + case 90: + value = 6; + break; + case 180: + value = 3; + break; + case 270: + value = 8; + break; + default: + break; + } + exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, value); + return true; +} + +bool ExifUtils::GenerateApp1() { + DestroyApp1(); + if (thumbnail_width_ > 0 && thumbnail_height_ > 0) { + if (!GenerateThumbnail()) { + LOGF(ERROR) << "Generate thumbnail image failed"; + return false; + } + exif_data_->data = const_cast( + static_cast(compressor_.GetCompressedImagePtr())); + exif_data_->size = compressor_.GetCompressedImageSize(); + } + // Save the result into |app1_buffer_|. + exif_data_save_data(exif_data_, &app1_buffer_, &app1_length_); + if (!app1_length_) { + LOGF(ERROR) << "Allocate memory for app1_buffer_ failed"; + return false; + } + /* + * The JPEG segment size is 16 bits in spec. The size of APP1 segment should + * be smaller than 65533 because there are two bytes for segment size field. + */ + if (app1_length_ > 65533) { + DestroyApp1(); + LOGF(ERROR) << "The size of APP1 segment is too large"; + return false; + } + return true; +} + +const uint8_t* ExifUtils::GetApp1Buffer() { return app1_buffer_; } + +unsigned int ExifUtils::GetApp1Length() { return app1_length_; } + +void ExifUtils::Reset() { + yu12_buffer_ = nullptr; + yu12_width_ = 0; + yu12_height_ = 0; + thumbnail_width_ = 0; + thumbnail_height_ = 0; + DestroyApp1(); + if (exif_data_) { + /* + * Since we decided to ignore the original APP1, we are sure that there is + * no thumbnail allocated by libexif. |exif_data_->data| is actually + * allocated by JpegCompressor. Sets |exif_data_->data| to nullptr to + * prevent exif_data_unref() destroy it incorrectly. + */ + exif_data_->data = nullptr; + exif_data_->size = 0; + exif_data_unref(exif_data_); + exif_data_ = nullptr; + } +} + +std::unique_ptr ExifUtils::AddVariableLengthEntry( + ExifIfd ifd, ExifTag tag, ExifFormat format, uint64_t components, + unsigned int size) { + // Remove old entry if exists. + exif_content_remove_entry(exif_data_->ifd[ifd], + exif_content_get_entry(exif_data_->ifd[ifd], tag)); + ExifMem* mem = exif_mem_new_default(); + if (!mem) { + LOGF(ERROR) << "Allocate memory for exif entry failed"; + return nullptr; + } + std::unique_ptr entry(exif_entry_new_mem(mem)); + if (!entry) { + LOGF(ERROR) << "Allocate memory for exif entry failed"; + exif_mem_unref(mem); + return nullptr; + } + void* tmpBuffer = exif_mem_alloc(mem, size); + if (!tmpBuffer) { + LOGF(ERROR) << "Allocate memory for exif entry failed"; + exif_mem_unref(mem); + return nullptr; + } + + entry->data = static_cast(tmpBuffer); + entry->tag = tag; + entry->format = format; + entry->components = components; + entry->size = size; + + exif_content_add_entry(exif_data_->ifd[ifd], entry.get()); + exif_mem_unref(mem); + + return entry; +} + +std::unique_ptr ExifUtils::AddEntry(ExifIfd ifd, ExifTag tag) { + std::unique_ptr entry( + exif_content_get_entry(exif_data_->ifd[ifd], tag)); + if (entry) { + // exif_content_get_entry() won't ref the entry, so we ref here. + exif_entry_ref(entry.get()); + return entry; + } + entry.reset(exif_entry_new()); + if (!entry) { + LOGF(ERROR) << "Allocate memory for exif entry failed"; + return nullptr; + } + entry->tag = tag; + exif_content_add_entry(exif_data_->ifd[ifd], entry.get()); + exif_entry_initialize(entry.get(), tag); + return entry; +} + +bool ExifUtils::SetImageWidth(uint16_t width) { + std::unique_ptr entry = AddEntry(EXIF_IFD_0, EXIF_TAG_IMAGE_WIDTH); + if (!entry) { + LOGF(ERROR) << "Adding ImageWidth exif entry failed"; + return false; + } + exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, width); + return true; +} + +bool ExifUtils::SetImageLength(uint16_t length) { + std::unique_ptr entry = + AddEntry(EXIF_IFD_0, EXIF_TAG_IMAGE_LENGTH); + if (!entry) { + LOGF(ERROR) << "Adding ImageLength exif entry failed"; + return false; + } + exif_set_short(entry->data, EXIF_BYTE_ORDER_INTEL, length); + return true; +} + +bool ExifUtils::GenerateThumbnail() { + // Resize yuv image to |thumbnail_width_| x |thumbnail_height_|. + std::vector scaled_buffer; + if (!GenerateYuvThumbnail(&scaled_buffer)) { + LOGF(ERROR) << "Generate YUV thumbnail failed"; + return false; + } + + // Compress thumbnail to JPEG. + if (!compressor_.CompressImage(scaled_buffer.data(), thumbnail_width_, + thumbnail_height_, thumbnail_jpeg_quality_, + NULL, 0)) { + LOGF(ERROR) << "Compress thumbnail failed"; + return false; + } + return true; +} + +bool ExifUtils::GenerateYuvThumbnail(std::vector* scaled_buffer) { + size_t y_plane_size = yu12_width_ * yu12_height_; + const uint8* y_plane = yu12_buffer_; + const uint8* u_plane = y_plane + y_plane_size; + const uint8* v_plane = u_plane + y_plane_size / 4; + + size_t scaled_y_plane_size = thumbnail_width_ * thumbnail_height_; + scaled_buffer->resize(scaled_y_plane_size * 3 / 2); + uint8* scaled_y_plane = scaled_buffer->data(); + uint8* scaled_u_plane = scaled_y_plane + scaled_y_plane_size; + uint8* scaled_v_plane = scaled_u_plane + scaled_y_plane_size / 4; + + int result = libyuv::I420Scale( + y_plane, yu12_width_, u_plane, yu12_width_ / 2, v_plane, yu12_width_ / 2, + yu12_width_, yu12_height_, scaled_y_plane, thumbnail_width_, + scaled_u_plane, thumbnail_width_ / 2, scaled_v_plane, + thumbnail_width_ / 2, thumbnail_width_, thumbnail_height_, + libyuv::kFilterNone); + if (result != 0) { + LOGF(ERROR) << "Scale I420 image failed"; + return false; + } + return true; +} + +void ExifUtils::DestroyApp1() { + /* + * Since there is no API to access ExifMem in ExifData->priv, we use free + * here, which is the default free function in libexif. See + * exif_data_save_data() for detail. + */ + free(app1_buffer_); + app1_buffer_ = nullptr; + app1_length_ = 0; +} + +} // namespace arc diff --git a/modules/camera/3_4/arc/exif_utils.h b/modules/camera/3_4/arc/exif_utils.h new file mode 100644 index 00000000..956ee1d2 --- /dev/null +++ b/modules/camera/3_4/arc/exif_utils.h @@ -0,0 +1,178 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef INCLUDE_ARC_EXIF_UTILS_H_ +#define INCLUDE_ARC_EXIF_UTILS_H_ + +#include +#include +#include +#include +#include + +extern "C" { +#include +} + +#include "arc/jpeg_compressor.h" + +namespace arc { + +// ExifUtils can generate APP1 segment with tags which caller set. ExifUtils can +// also add a thumbnail in the APP1 segment if thumbnail size is specified. +// ExifUtils can be reused with different images by calling initialize(). +// +// Example of using this class : +// ExifUtils utils; +// utils.initialize(inputYU12Buffer, inputWidth, inputHeight, +// outputJpegQuality); +// ... +// // Call ExifUtils functions to set Exif tags. +// ... +// utils.generateApp1(); +// unsigned int app1Length = utils.getApp1Length(); +// uint8_t* app1Buffer = new uint8_t[app1Length]; +// memcpy(app1Buffer, utils.getApp1Buffer(), app1Length); +class ExifUtils { + public: + ExifUtils(); + ~ExifUtils(); + + // Sets input YU12 image |buffer| with |width| x |height|. |quality| is the + // compressed JPEG image quality. The caller should not release |buffer| until + // generateApp1() or the destructor is called. initialize() can be called + // multiple times. The setting of Exif tags will be cleared. + bool Initialize(const uint8_t* buffer, uint16_t width, uint16_t height, + int quality); + + // Sets the manufacturer of camera. + // Returns false if memory allocation fails. + bool SetMaker(const std::string& maker); + + // Sets the model number of camera. + // Returns false if memory allocation fails. + bool SetModel(const std::string& model); + + // Sets the date and time of image last modified. It takes local time. The + // name of the tag is DateTime in IFD0. + // Returns false if memory allocation fails. + bool SetDateTime(const struct tm& t); + + // Sets the focal length of lens used to take the image in millimeters. + // Returns false if memory allocation fails. + bool SetFocalLength(uint32_t numerator, uint32_t denominator); + + // Sets the latitude with degrees minutes seconds format. + // Returns false if memory allocation fails. + bool SetGpsLatitude(double latitude); + + // Sets the longitude with degrees minutes seconds format. + // Returns false if memory allocation fails. + bool SetGpsLongitude(double longitude); + + // Sets the altitude in meters. + // Returns false if memory allocation fails. + bool SetGpsAltitude(double altitude); + + // Sets GPS date stamp and time stamp (atomic clock). It takes UTC time. + // Returns false if memory allocation fails. + bool SetGpsTimestamp(const struct tm& t); + + // Sets GPS processing method. + // Returns false if memory allocation fails. + bool SetGpsProcessingMethod(const std::string& method); + + // Since the size of APP1 segment is limited, it is recommended the + // resolution of thumbnail is equal to or smaller than 640x480. If the + // thumbnail is too big, generateApp1() will return false. + // Returns false if |width| or |height| is not even. + bool SetThumbnailSize(uint16_t width, uint16_t height); + + // Sets image orientation. + // Returns false if memory allocation fails. + bool SetOrientation(uint16_t orientation); + + // Generates APP1 segment. + // Returns false if generating APP1 segment fails. + bool GenerateApp1(); + + // Gets buffer of APP1 segment. This method must be called only after calling + // generateAPP1(). + const uint8_t* GetApp1Buffer(); + + // Gets length of APP1 segment. This method must be called only after calling + // generateAPP1(). + unsigned int GetApp1Length(); + + private: + // Resets the pointers and memories. + void Reset(); + + // Adds a variable length tag to |exif_data_|. It will remove the original one + // if the tag exists. + // Returns the entry of the tag. The reference count of returned ExifEntry is + // two. + std::unique_ptr AddVariableLengthEntry(ExifIfd ifd, ExifTag tag, + ExifFormat format, + uint64_t components, + unsigned int size); + + // Adds a entry of |tag| in |exif_data_|. It won't remove the original one if + // the tag exists. + // Returns the entry of the tag. It adds one reference count to returned + // ExifEntry. + std::unique_ptr AddEntry(ExifIfd ifd, ExifTag tag); + + // Sets the width (number of columes) of main image. + // Returns false if memory allocation fails. + bool SetImageWidth(uint16_t width); + + // Sets the length (number of rows) of main image. + // Returns false if memory allocation fails. + bool SetImageLength(uint16_t length); + + // Generates a thumbnail. Calls compressor_.getCompressedImagePtr() to get the + // result image. + // Returns false if failed. + bool GenerateThumbnail(); + + // Resizes the thumbnail yuv image to |thumbnail_width_| x |thumbnail_height_| + // and stores in |scaled_buffer|. + // Returns false if scale image failed. + bool GenerateYuvThumbnail(std::vector* scaled_buffer); + + // Destroys the buffer of APP1 segment if exists. + void DestroyApp1(); + + // The buffer pointer of yuv image (YU12). Not owned by this class. + const uint8_t* yu12_buffer_; + // The size of yuv image. + uint16_t yu12_width_; + uint16_t yu12_height_; + + // The size of thumbnail. + uint16_t thumbnail_width_; + uint16_t thumbnail_height_; + + // The Exif data (APP1). Owned by this class. + ExifData* exif_data_; + // The raw data of APP1 segment. It's allocated by ExifMem in |exif_data_| but + // owned by this class. + uint8_t* app1_buffer_; + // The length of |app1_buffer_|. + unsigned int app1_length_; + // The quality of compressed thumbnail image. The size of EXIF thumbnail has + // to be smaller than 64KB. If quality is 100, the size may be bigger than + // 64KB. + int thumbnail_jpeg_quality_; + + // The YU12 to Jpeg compressor. + JpegCompressor compressor_; +}; + +} // namespace arc + +#endif // INCLUDE_ARC_EXIF_UTILS_H_ diff --git a/modules/camera/3_4/arc/frame_buffer.cpp b/modules/camera/3_4/arc/frame_buffer.cpp new file mode 100644 index 00000000..4ae0fe39 --- /dev/null +++ b/modules/camera/3_4/arc/frame_buffer.cpp @@ -0,0 +1,188 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "arc/frame_buffer.h" + +#include + +#include + +#include "arc/common.h" +#include "arc/image_processor.h" + +namespace arc { + +FrameBuffer::FrameBuffer() + : data_(nullptr), + data_size_(0), + buffer_size_(0), + width_(0), + height_(0), + fourcc_(0) {} + +FrameBuffer::~FrameBuffer() {} + +int FrameBuffer::SetDataSize(size_t data_size) { + if (data_size > buffer_size_) { + LOGF(ERROR) << "Buffer overflow: Buffer only has " << buffer_size_ + << ", but data needs " << data_size; + return -EINVAL; + } + data_size_ = data_size; + return 0; +} + +AllocatedFrameBuffer::AllocatedFrameBuffer(int buffer_size) { + buffer_.reset(new uint8_t[buffer_size]); + buffer_size_ = buffer_size; + data_ = buffer_.get(); +} + +AllocatedFrameBuffer::AllocatedFrameBuffer(uint8_t* buffer, int buffer_size) { + buffer_.reset(buffer); + buffer_size_ = buffer_size; + data_ = buffer_.get(); +} + +AllocatedFrameBuffer::~AllocatedFrameBuffer() {} + +int AllocatedFrameBuffer::SetDataSize(size_t size) { + if (size > buffer_size_) { + buffer_.reset(new uint8_t[size]); + buffer_size_ = size; + data_ = buffer_.get(); + } + data_size_ = size; + return 0; +} + +void AllocatedFrameBuffer::Reset() { memset(data_, 0, buffer_size_); } + +V4L2FrameBuffer::V4L2FrameBuffer(base::ScopedFD fd, int buffer_size, + uint32_t width, uint32_t height, + uint32_t fourcc) + : fd_(std::move(fd)), is_mapped_(false) { + buffer_size_ = buffer_size; + width_ = width; + height_ = height; + fourcc_ = fourcc; +} + +V4L2FrameBuffer::~V4L2FrameBuffer() { + if (Unmap()) { + LOGF(ERROR) << "Unmap failed"; + } +} + +int V4L2FrameBuffer::Map() { + base::AutoLock l(lock_); + if (is_mapped_) { + LOGF(ERROR) << "The buffer is already mapped"; + return -EINVAL; + } + void* addr = mmap(NULL, buffer_size_, PROT_READ, MAP_SHARED, fd_.get(), 0); + if (addr == MAP_FAILED) { + LOGF(ERROR) << "mmap() failed: " << strerror(errno); + return -EINVAL; + } + data_ = static_cast(addr); + is_mapped_ = true; + return 0; +} + +int V4L2FrameBuffer::Unmap() { + base::AutoLock l(lock_); + if (is_mapped_ && munmap(data_, buffer_size_)) { + LOGF(ERROR) << "mummap() failed: " << strerror(errno); + return -EINVAL; + } + is_mapped_ = false; + return 0; +} + +GrallocFrameBuffer::GrallocFrameBuffer(buffer_handle_t buffer, uint32_t width, + uint32_t height, uint32_t fourcc, + uint32_t device_buffer_length, + uint32_t stream_usage) + : buffer_(buffer), + is_mapped_(false), + device_buffer_length_(device_buffer_length), + stream_usage_(stream_usage) { + const hw_module_t* module = nullptr; + int ret = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); + if (ret || !module) { + LOGF(ERROR) << "Failed to get gralloc module."; + return; + } + gralloc_module_ = reinterpret_cast(module); + width_ = width; + height_ = height; + fourcc_ = fourcc; +} + +GrallocFrameBuffer::~GrallocFrameBuffer() { + if (Unmap()) { + LOGF(ERROR) << "Unmap failed"; + } +} + +int GrallocFrameBuffer::Map() { + base::AutoLock l(lock_); + if (is_mapped_) { + LOGF(ERROR) << "The buffer is already mapped"; + return -EINVAL; + } + + void* addr; + int ret = 0; + switch (fourcc_) { + case V4L2_PIX_FMT_YUV420: + case V4L2_PIX_FMT_YVU420: + case V4L2_PIX_FMT_YUYV: + android_ycbcr yuv_data; + ret = gralloc_module_->lock_ycbcr(gralloc_module_, buffer_, stream_usage_, + 0, 0, width_, height_, &yuv_data); + addr = yuv_data.y; + break; + case V4L2_PIX_FMT_JPEG: + ret = gralloc_module_->lock(gralloc_module_, buffer_, stream_usage_, 0, 0, + device_buffer_length_, 1, &addr); + break; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + ret = gralloc_module_->lock(gralloc_module_, buffer_, stream_usage_, 0, 0, + width_, height_, &addr); + break; + default: + return -EINVAL; + } + + if (ret) { + LOGF(ERROR) << "Failed to gralloc lock buffer: " << ret; + return ret; + } + + data_ = static_cast(addr); + if (fourcc_ == V4L2_PIX_FMT_YVU420 || fourcc_ == V4L2_PIX_FMT_YUV420 || + fourcc_ == V4L2_PIX_FMT_NV21 || fourcc_ == V4L2_PIX_FMT_RGB32 || + fourcc_ == V4L2_PIX_FMT_BGR32) { + buffer_size_ = ImageProcessor::GetConvertedSize(fourcc_, width_, height_); + } + + is_mapped_ = true; + return 0; +} + +int GrallocFrameBuffer::Unmap() { + base::AutoLock l(lock_); + if (is_mapped_ && gralloc_module_->unlock(gralloc_module_, buffer_)) { + LOGF(ERROR) << "Failed to unmap buffer: "; + return -EINVAL; + } + is_mapped_ = false; + return 0; +} + +} // namespace arc diff --git a/modules/camera/3_4/arc/frame_buffer.h b/modules/camera/3_4/arc/frame_buffer.h new file mode 100644 index 00000000..3efeb3ba --- /dev/null +++ b/modules/camera/3_4/arc/frame_buffer.h @@ -0,0 +1,135 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef HAL_USB_FRAME_BUFFER_H_ +#define HAL_USB_FRAME_BUFFER_H_ + +#include + +#include +#include + +#include +#include + +#include + +namespace arc { + +class FrameBuffer { + public: + FrameBuffer(); + virtual ~FrameBuffer(); + + // If mapped successfully, the address will be assigned to |data_| and return + // 0. Otherwise, returns -EINVAL. + virtual int Map() = 0; + + // Unmaps the mapped address. Returns 0 for success. + virtual int Unmap() = 0; + + uint8_t* GetData() const { return data_; } + size_t GetDataSize() const { return data_size_; } + size_t GetBufferSize() const { return buffer_size_; } + uint32_t GetWidth() const { return width_; } + uint32_t GetHeight() const { return height_; } + uint32_t GetFourcc() const { return fourcc_; } + + void SetFourcc(uint32_t fourcc) { fourcc_ = fourcc; } + virtual int SetDataSize(size_t data_size); + + protected: + uint8_t* data_; + + // The number of bytes used in the buffer. + size_t data_size_; + + // The number of bytes allocated in the buffer. + size_t buffer_size_; + + // Frame resolution. + uint32_t width_; + uint32_t height_; + + // This is V4L2_PIX_FMT_* in linux/videodev2.h. + uint32_t fourcc_; +}; + +// AllocatedFrameBuffer is used for the buffer from hal malloc-ed. User should +// be aware to manage the memory. +class AllocatedFrameBuffer : public FrameBuffer { + public: + explicit AllocatedFrameBuffer(int buffer_size); + explicit AllocatedFrameBuffer(uint8_t* buffer, int buffer_size); + ~AllocatedFrameBuffer() override; + + // No-op for the two functions. + int Map() override { return 0; } + int Unmap() override { return 0; } + + void SetWidth(uint32_t width) { width_ = width; } + void SetHeight(uint32_t height) { height_ = height; } + int SetDataSize(size_t data_size) override; + void Reset(); + + private: + std::unique_ptr buffer_; +}; + +// V4L2FrameBuffer is used for the buffer from V4L2CameraDevice. Maps the fd +// in constructor. Unmaps and closes the fd in destructor. +class V4L2FrameBuffer : public FrameBuffer { + public: + V4L2FrameBuffer(base::ScopedFD fd, int buffer_size, uint32_t width, + uint32_t height, uint32_t fourcc); + // Unmaps |data_| and closes |fd_|. + ~V4L2FrameBuffer(); + + int Map() override; + int Unmap() override; + int GetFd() const { return fd_.get(); } + + private: + // File descriptor of V4L2 frame buffer. + base::ScopedFD fd_; + + bool is_mapped_; + + // Lock to guard |is_mapped_|. + base::Lock lock_; +}; + +// GrallocFrameBuffer is used for the buffer from Android framework. Uses +// CameraBufferMapper to lock and unlock the buffer. +class GrallocFrameBuffer : public FrameBuffer { + public: + GrallocFrameBuffer(buffer_handle_t buffer, uint32_t width, uint32_t height, + uint32_t fourcc, uint32_t device_buffer_length, + uint32_t stream_usage); + ~GrallocFrameBuffer(); + + int Map() override; + int Unmap() override; + + private: + // The currently used buffer for |buffer_mapper_| operations. + buffer_handle_t buffer_; + + // Used to import gralloc buffer. + const gralloc_module_t* gralloc_module_; + + bool is_mapped_; + + // Lock to guard |is_mapped_|. + base::Lock lock_; + + // Camera stream and device buffer context. + uint32_t device_buffer_length_; + uint32_t stream_usage_; +}; + +} // namespace arc + +#endif // HAL_USB_FRAME_BUFFER_H_ diff --git a/modules/camera/3_4/arc/image_processor.cpp b/modules/camera/3_4/arc/image_processor.cpp new file mode 100644 index 00000000..f0fee918 --- /dev/null +++ b/modules/camera/3_4/arc/image_processor.cpp @@ -0,0 +1,491 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "arc/image_processor.h" + +#include +#include +#include + +#include "arc/common.h" +#include "arc/common_types.h" +#include "arc/exif_utils.h" +#include "arc/jpeg_compressor.h" + +namespace arc { + +using android::CameraMetadata; + +/* + * Formats have different names in different header files. Here is the mapping + * table: + * + * android_pixel_format_t videodev2.h FOURCC in libyuv + * ----------------------------------------------------------------------------- + * HAL_PIXEL_FORMAT_YV12 = V4L2_PIX_FMT_YVU420 = FOURCC_YV12 + * HAL_PIXEL_FORMAT_YCrCb_420_SP = V4L2_PIX_FMT_NV21 = FOURCC_NV21 + * HAL_PIXEL_FORMAT_RGBA_8888 = V4L2_PIX_FMT_RGB32 = FOURCC_BGR4 + * HAL_PIXEL_FORMAT_YCbCr_422_I = V4L2_PIX_FMT_YUYV = FOURCC_YUYV + * = FOURCC_YUY2 + * V4L2_PIX_FMT_YUV420 = FOURCC_I420 + * = FOURCC_YU12 + * V4L2_PIX_FMT_MJPEG = FOURCC_MJPG + * + * Camera device generates FOURCC_YUYV and FOURCC_MJPG. + * Preview needs FOURCC_ARGB format. + * Software video encoder needs FOURCC_YU12. + * CTS requires FOURCC_YV12 and FOURCC_NV21 for applications. + * + * Android stride requirement: + * YV12 horizontal stride should be a multiple of 16 pixels. See + * android.graphics.ImageFormat.YV12. + * The stride of ARGB, YU12, and NV21 are always equal to the width. + * + * Conversion Path: + * MJPG/YUYV (from camera) -> YU12 -> ARGB (preview) + * -> NV21 (apps) + * -> YV12 (apps) + * -> YU12 (video encoder) + */ + +// YV12 horizontal stride should be a multiple of 16 pixels for each plane. +// |dst_stride_uv| is the pixel stride of u or v plane. +static int YU12ToYV12(const void* yv12, void* yu12, int width, int height, + int dst_stride_y, int dst_stride_uv); +static int YU12ToNV21(const void* yv12, void* nv21, int width, int height); +static bool ConvertToJpeg(const CameraMetadata& metadata, + const FrameBuffer& in_frame, FrameBuffer* out_frame); +static bool SetExifTags(const CameraMetadata& metadata, ExifUtils* utils); + +// How precise the float-to-rational conversion for EXIF tags would be. +static const int kRationalPrecision = 10000; + +// Default JPEG quality settings. +static const int DEFAULT_JPEG_QUALITY = 80; + +inline static size_t Align16(size_t value) { return (value + 15) & ~15; } + +size_t ImageProcessor::GetConvertedSize(int fourcc, uint32_t width, + uint32_t height) { + if ((width % 2) || (height % 2)) { + LOGF(ERROR) << "Width or height is not even (" << width << " x " << height + << ")"; + return 0; + } + + switch (fourcc) { + case V4L2_PIX_FMT_YVU420: // YV12 + return Align16(width) * height + Align16(width / 2) * height; + case V4L2_PIX_FMT_YUV420: // YU12 + // Fall-through. + case V4L2_PIX_FMT_NV21: // NV21 + return width * height * 3 / 2; + case V4L2_PIX_FMT_BGR32: + case V4L2_PIX_FMT_RGB32: + return width * height * 4; + default: + LOGF(ERROR) << "Pixel format " << FormatToString(fourcc) + << " is unsupported."; + return 0; + } +} + +bool ImageProcessor::SupportsConversion(uint32_t from_fourcc, + uint32_t to_fourcc) { + switch (from_fourcc) { + case V4L2_PIX_FMT_YUYV: + return (to_fourcc == V4L2_PIX_FMT_YUV420); + case V4L2_PIX_FMT_YUV420: + return ( + to_fourcc == V4L2_PIX_FMT_YUV420 || + to_fourcc == V4L2_PIX_FMT_YVU420 || to_fourcc == V4L2_PIX_FMT_NV21 || + to_fourcc == V4L2_PIX_FMT_RGB32 || to_fourcc == V4L2_PIX_FMT_BGR32 || + to_fourcc == V4L2_PIX_FMT_JPEG); + case V4L2_PIX_FMT_MJPEG: + return (to_fourcc == V4L2_PIX_FMT_YUV420); + default: + return false; + } +} + +int ImageProcessor::ConvertFormat(const CameraMetadata& metadata, + const FrameBuffer& in_frame, + FrameBuffer* out_frame) { + if ((in_frame.GetWidth() % 2) || (in_frame.GetHeight() % 2)) { + LOGF(ERROR) << "Width or height is not even (" << in_frame.GetWidth() + << " x " << in_frame.GetHeight() << ")"; + return -EINVAL; + } + + size_t data_size = GetConvertedSize( + out_frame->GetFourcc(), in_frame.GetWidth(), in_frame.GetHeight()); + + if (out_frame->SetDataSize(data_size)) { + LOGF(ERROR) << "Set data size failed"; + return -EINVAL; + } + + if (in_frame.GetFourcc() == V4L2_PIX_FMT_YUYV) { + switch (out_frame->GetFourcc()) { + case V4L2_PIX_FMT_YUV420: // YU12 + { + int res = libyuv::YUY2ToI420( + in_frame.GetData(), /* src_yuy2 */ + in_frame.GetWidth() * 2, /* src_stride_yuy2 */ + out_frame->GetData(), /* dst_y */ + out_frame->GetWidth(), /* dst_stride_y */ + out_frame->GetData() + + out_frame->GetWidth() * out_frame->GetHeight(), /* dst_u */ + out_frame->GetWidth() / 2, /* dst_stride_u */ + out_frame->GetData() + out_frame->GetWidth() * + out_frame->GetHeight() * 5 / + 4, /* dst_v */ + out_frame->GetWidth() / 2, /* dst_stride_v */ + in_frame.GetWidth(), in_frame.GetHeight()); + LOGF_IF(ERROR, res) << "YUY2ToI420() for YU12 returns " << res; + return res ? -EINVAL : 0; + } + default: + LOGF(ERROR) << "Destination pixel format " + << FormatToString(out_frame->GetFourcc()) + << " is unsupported for YUYV source format."; + return -EINVAL; + } + } else if (in_frame.GetFourcc() == V4L2_PIX_FMT_YUV420) { + // V4L2_PIX_FMT_YVU420 is YV12. I420 is usually referred to YU12 + // (V4L2_PIX_FMT_YUV420), and YV12 is similar to YU12 except that U/V + // planes are swapped. + switch (out_frame->GetFourcc()) { + case V4L2_PIX_FMT_YVU420: // YV12 + { + int ystride = Align16(in_frame.GetWidth()); + int uvstride = Align16(in_frame.GetWidth() / 2); + int res = YU12ToYV12(in_frame.GetData(), out_frame->GetData(), + in_frame.GetWidth(), in_frame.GetHeight(), ystride, + uvstride); + LOGF_IF(ERROR, res) << "YU12ToYV12() returns " << res; + return res ? -EINVAL : 0; + } + case V4L2_PIX_FMT_YUV420: // YU12 + { + memcpy(out_frame->GetData(), in_frame.GetData(), + in_frame.GetDataSize()); + return 0; + } + case V4L2_PIX_FMT_NV21: // NV21 + { + // TODO(henryhsu): Use libyuv::I420ToNV21. + int res = YU12ToNV21(in_frame.GetData(), out_frame->GetData(), + in_frame.GetWidth(), in_frame.GetHeight()); + LOGF_IF(ERROR, res) << "YU12ToNV21() returns " << res; + return res ? -EINVAL : 0; + } + case V4L2_PIX_FMT_BGR32: { + int res = libyuv::I420ToABGR( + in_frame.GetData(), /* src_y */ + in_frame.GetWidth(), /* src_stride_y */ + in_frame.GetData() + + in_frame.GetWidth() * in_frame.GetHeight(), /* src_u */ + in_frame.GetWidth() / 2, /* src_stride_u */ + in_frame.GetData() + + in_frame.GetWidth() * in_frame.GetHeight() * 5 / 4, /* src_v */ + in_frame.GetWidth() / 2, /* src_stride_v */ + out_frame->GetData(), /* dst_abgr */ + out_frame->GetWidth() * 4, /* dst_stride_abgr */ + in_frame.GetWidth(), in_frame.GetHeight()); + LOGF_IF(ERROR, res) << "I420ToABGR() returns " << res; + return res ? -EINVAL : 0; + } + case V4L2_PIX_FMT_RGB32: { + int res = libyuv::I420ToARGB( + in_frame.GetData(), /* src_y */ + in_frame.GetWidth(), /* src_stride_y */ + in_frame.GetData() + + in_frame.GetWidth() * in_frame.GetHeight(), /* src_u */ + in_frame.GetWidth() / 2, /* src_stride_u */ + in_frame.GetData() + + in_frame.GetWidth() * in_frame.GetHeight() * 5 / 4, /* src_v */ + in_frame.GetWidth() / 2, /* src_stride_v */ + out_frame->GetData(), /* dst_argb */ + out_frame->GetWidth() * 4, /* dst_stride_argb */ + in_frame.GetWidth(), in_frame.GetHeight()); + LOGF_IF(ERROR, res) << "I420ToARGB() returns " << res; + return res ? -EINVAL : 0; + } + case V4L2_PIX_FMT_JPEG: { + bool res = ConvertToJpeg(metadata, in_frame, out_frame); + LOGF_IF(ERROR, !res) << "ConvertToJpeg() returns " << res; + return res ? -EINVAL : 0; + } + default: + LOGF(ERROR) << "Destination pixel format " + << FormatToString(out_frame->GetFourcc()) + << " is unsupported for YU12 source format."; + return -EINVAL; + } + } else if (in_frame.GetFourcc() == V4L2_PIX_FMT_MJPEG) { + switch (out_frame->GetFourcc()) { + case V4L2_PIX_FMT_YUV420: // YU12 + { + int res = libyuv::MJPGToI420( + in_frame.GetData(), /* sample */ + in_frame.GetDataSize(), /* sample_size */ + out_frame->GetData(), /* dst_y */ + out_frame->GetWidth(), /* dst_stride_y */ + out_frame->GetData() + + out_frame->GetWidth() * out_frame->GetHeight(), /* dst_u */ + out_frame->GetWidth() / 2, /* dst_stride_u */ + out_frame->GetData() + out_frame->GetWidth() * + out_frame->GetHeight() * 5 / + 4, /* dst_v */ + out_frame->GetWidth() / 2, /* dst_stride_v */ + in_frame.GetWidth(), in_frame.GetHeight(), out_frame->GetWidth(), + out_frame->GetHeight()); + LOGF_IF(ERROR, res) << "MJPEGToI420() returns " << res; + return res ? -EINVAL : 0; + } + default: + LOGF(ERROR) << "Destination pixel format " + << FormatToString(out_frame->GetFourcc()) + << " is unsupported for MJPEG source format."; + return -EINVAL; + } + } else { + LOGF(ERROR) << "Convert format doesn't support source format " + << FormatToString(in_frame.GetFourcc()); + return -EINVAL; + } +} + +int ImageProcessor::Scale(const FrameBuffer& in_frame, FrameBuffer* out_frame) { + if (in_frame.GetFourcc() != V4L2_PIX_FMT_YUV420) { + LOGF(ERROR) << "Pixel format " << FormatToString(in_frame.GetFourcc()) + << " is unsupported."; + return -EINVAL; + } + + size_t data_size = GetConvertedSize( + in_frame.GetFourcc(), out_frame->GetWidth(), out_frame->GetHeight()); + + if (out_frame->SetDataSize(data_size)) { + LOGF(ERROR) << "Set data size failed"; + return -EINVAL; + } + out_frame->SetFourcc(in_frame.GetFourcc()); + + VLOGF(1) << "Scale image from " << in_frame.GetWidth() << "x" + << in_frame.GetHeight() << " to " << out_frame->GetWidth() << "x" + << out_frame->GetHeight(); + + int ret = libyuv::I420Scale( + in_frame.GetData(), in_frame.GetWidth(), + in_frame.GetData() + in_frame.GetWidth() * in_frame.GetHeight(), + in_frame.GetWidth() / 2, + in_frame.GetData() + in_frame.GetWidth() * in_frame.GetHeight() * 5 / 4, + in_frame.GetWidth() / 2, in_frame.GetWidth(), in_frame.GetHeight(), + out_frame->GetData(), out_frame->GetWidth(), + out_frame->GetData() + out_frame->GetWidth() * out_frame->GetHeight(), + out_frame->GetWidth() / 2, + out_frame->GetData() + + out_frame->GetWidth() * out_frame->GetHeight() * 5 / 4, + out_frame->GetWidth() / 2, out_frame->GetWidth(), out_frame->GetHeight(), + libyuv::FilterMode::kFilterNone); + LOGF_IF(ERROR, ret) << "I420Scale failed: " << ret; + return ret; +} + +static int YU12ToYV12(const void* yu12, void* yv12, int width, int height, + int dst_stride_y, int dst_stride_uv) { + if ((width % 2) || (height % 2)) { + LOGF(ERROR) << "Width or height is not even (" << width << " x " << height + << ")"; + return -EINVAL; + } + if (dst_stride_y < width || dst_stride_uv < width / 2) { + LOGF(ERROR) << "Y plane stride (" << dst_stride_y + << ") or U/V plane stride (" << dst_stride_uv + << ") is invalid for width " << width; + return -EINVAL; + } + + const uint8_t* src = reinterpret_cast(yu12); + uint8_t* dst = reinterpret_cast(yv12); + const uint8_t* u_src = src + width * height; + uint8_t* u_dst = dst + dst_stride_y * height + dst_stride_uv * height / 2; + const uint8_t* v_src = src + width * height * 5 / 4; + uint8_t* v_dst = dst + dst_stride_y * height; + + return libyuv::I420Copy(src, width, u_src, width / 2, v_src, width / 2, dst, + dst_stride_y, u_dst, dst_stride_uv, v_dst, + dst_stride_uv, width, height); +} + +static int YU12ToNV21(const void* yu12, void* nv21, int width, int height) { + if ((width % 2) || (height % 2)) { + LOGF(ERROR) << "Width or height is not even (" << width << " x " << height + << ")"; + return -EINVAL; + } + + const uint8_t* src = reinterpret_cast(yu12); + uint8_t* dst = reinterpret_cast(nv21); + const uint8_t* u_src = src + width * height; + const uint8_t* v_src = src + width * height * 5 / 4; + uint8_t* vu_dst = dst + width * height; + + memcpy(dst, src, width * height); + + for (int i = 0; i < height / 2; i++) { + for (int j = 0; j < width / 2; j++) { + *vu_dst++ = *v_src++; + *vu_dst++ = *u_src++; + } + } + return 0; +} + +static bool ConvertToJpeg(const CameraMetadata& metadata, + const FrameBuffer& in_frame, FrameBuffer* out_frame) { + ExifUtils utils; + int jpeg_quality, thumbnail_jpeg_quality; + camera_metadata_ro_entry entry; + + if (metadata.exists(ANDROID_JPEG_QUALITY)) { + entry = metadata.find(ANDROID_JPEG_QUALITY); + jpeg_quality = entry.data.u8[0]; + } else { + LOGF(ERROR) << "Could not find jpeg quality in metadata, defaulting to " + << DEFAULT_JPEG_QUALITY; + jpeg_quality = DEFAULT_JPEG_QUALITY; + } + if (metadata.exists(ANDROID_JPEG_THUMBNAIL_QUALITY)) { + entry = metadata.find(ANDROID_JPEG_THUMBNAIL_QUALITY); + thumbnail_jpeg_quality = entry.data.u8[0]; + } else { + thumbnail_jpeg_quality = jpeg_quality; + } + + if (!utils.Initialize(in_frame.GetData(), in_frame.GetWidth(), + in_frame.GetHeight(), thumbnail_jpeg_quality)) { + LOGF(ERROR) << "ExifUtils initialization failed."; + return false; + } + if (!SetExifTags(metadata, &utils)) { + LOGF(ERROR) << "Setting Exif tags failed."; + return false; + } + if (!utils.GenerateApp1()) { + LOGF(ERROR) << "Generating APP1 segment failed."; + return false; + } + JpegCompressor compressor; + if (!compressor.CompressImage(in_frame.GetData(), in_frame.GetWidth(), + in_frame.GetHeight(), jpeg_quality, + utils.GetApp1Buffer(), utils.GetApp1Length())) { + LOGF(ERROR) << "JPEG image compression failed"; + return false; + } + size_t buffer_length = compressor.GetCompressedImageSize(); + memcpy(out_frame->GetData(), compressor.GetCompressedImagePtr(), + buffer_length); + return true; +} + +static bool SetExifTags(const CameraMetadata& metadata, ExifUtils* utils) { + time_t raw_time = 0; + struct tm time_info; + bool time_available = time(&raw_time) != -1; + localtime_r(&raw_time, &time_info); + if (!utils->SetDateTime(time_info)) { + LOGF(ERROR) << "Setting data time failed."; + return false; + } + + float focal_length; + camera_metadata_ro_entry entry = metadata.find(ANDROID_LENS_FOCAL_LENGTH); + if (entry.count) { + focal_length = entry.data.f[0]; + } else { + LOGF(ERROR) << "Cannot find focal length in metadata."; + return false; + } + if (!utils->SetFocalLength( + static_cast(focal_length * kRationalPrecision), + kRationalPrecision)) { + LOGF(ERROR) << "Setting focal length failed."; + return false; + } + + if (metadata.exists(ANDROID_JPEG_GPS_COORDINATES)) { + entry = metadata.find(ANDROID_JPEG_GPS_COORDINATES); + if (entry.count < 3) { + LOGF(ERROR) << "Gps coordinates in metadata is not complete."; + return false; + } + if (!utils->SetGpsLatitude(entry.data.d[0])) { + LOGF(ERROR) << "Setting gps latitude failed."; + return false; + } + if (!utils->SetGpsLongitude(entry.data.d[1])) { + LOGF(ERROR) << "Setting gps longitude failed."; + return false; + } + if (!utils->SetGpsAltitude(entry.data.d[2])) { + LOGF(ERROR) << "Setting gps altitude failed."; + return false; + } + } + + if (metadata.exists(ANDROID_JPEG_GPS_PROCESSING_METHOD)) { + entry = metadata.find(ANDROID_JPEG_GPS_PROCESSING_METHOD); + std::string method_str(reinterpret_cast(entry.data.u8)); + if (!utils->SetGpsProcessingMethod(method_str)) { + LOGF(ERROR) << "Setting gps processing method failed."; + return false; + } + } + + if (time_available && metadata.exists(ANDROID_JPEG_GPS_TIMESTAMP)) { + entry = metadata.find(ANDROID_JPEG_GPS_TIMESTAMP); + time_t timestamp = static_cast(entry.data.i64[0]); + if (gmtime_r(×tamp, &time_info)) { + if (!utils->SetGpsTimestamp(time_info)) { + LOGF(ERROR) << "Setting gps timestamp failed."; + return false; + } + } else { + LOGF(ERROR) << "Time tranformation failed."; + return false; + } + } + + if (metadata.exists(ANDROID_JPEG_ORIENTATION)) { + entry = metadata.find(ANDROID_JPEG_ORIENTATION); + if (!utils->SetOrientation(entry.data.i32[0])) { + LOGF(ERROR) << "Setting orientation failed."; + return false; + } + } + + if (metadata.exists(ANDROID_JPEG_THUMBNAIL_SIZE)) { + entry = metadata.find(ANDROID_JPEG_THUMBNAIL_SIZE); + if (entry.count < 2) { + LOGF(ERROR) << "Thumbnail size in metadata is not complete."; + return false; + } + int thumbnail_width = entry.data.i32[0]; + int thumbnail_height = entry.data.i32[1]; + if (thumbnail_width > 0 && thumbnail_height > 0) { + if (!utils->SetThumbnailSize(static_cast(thumbnail_width), + static_cast(thumbnail_height))) { + LOGF(ERROR) << "Setting thumbnail size failed."; + return false; + } + } + } + return true; +} + +} // namespace arc diff --git a/modules/camera/3_4/arc/image_processor.h b/modules/camera/3_4/arc/image_processor.h new file mode 100644 index 00000000..323680ab --- /dev/null +++ b/modules/camera/3_4/arc/image_processor.h @@ -0,0 +1,48 @@ +/* Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef HAL_USB_IMAGE_PROCESSOR_H_ +#define HAL_USB_IMAGE_PROCESSOR_H_ + +#include + +// FourCC pixel formats (defined as V4L2_PIX_FMT_*). +#include +// Declarations of HAL_PIXEL_FORMAT_XXX. +#include + +#include +#include "frame_buffer.h" + +namespace arc { + +// V4L2_PIX_FMT_YVU420(YV12) in ImageProcessor has alignment requirement. +// The stride of Y, U, and V planes should a multiple of 16 pixels. +struct ImageProcessor { + // Calculate the output buffer size when converting to the specified pixel + // format. |fourcc| is defined as V4L2_PIX_FMT_* in linux/videodev2.h. + // Return 0 on error. + static size_t GetConvertedSize(int fourcc, uint32_t width, uint32_t height); + + // Return whether this class supports the provided conversion. + static bool SupportsConversion(uint32_t from_fourcc, uint32_t to_fourcc); + + // Convert format from |in_frame.fourcc| to |out_frame->fourcc|. Caller should + // fill |data|, |buffer_size|, |width|, and |height| of |out_frame|. The + // function will fill |out_frame->data_size|. Return non-zero error code on + // failure; return 0 on success. + static int ConvertFormat(const android::CameraMetadata& metadata, + const FrameBuffer& in_frame, FrameBuffer* out_frame); + + // Scale image size according to |in_frame| and |out_frame|. Only support + // V4L2_PIX_FMT_YUV420 format. Caller should fill |data|, |width|, |height|, + // and |buffer_size| of |out_frame|. The function will fill |data_size| and + // |fourcc| of |out_frame|. + static int Scale(const FrameBuffer& in_frame, FrameBuffer* out_frame); +}; + +} // namespace arc + +#endif // HAL_USB_IMAGE_PROCESSOR_H_ diff --git a/modules/camera/3_4/arc/jpeg_compressor.cpp b/modules/camera/3_4/arc/jpeg_compressor.cpp new file mode 100644 index 00000000..7c61b404 --- /dev/null +++ b/modules/camera/3_4/arc/jpeg_compressor.cpp @@ -0,0 +1,190 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "arc/jpeg_compressor.h" + +#include + +#include + +#include "arc/common.h" + +namespace arc { + +// The destination manager that can access |result_buffer_| in JpegCompressor. +struct destination_mgr { + public: + struct jpeg_destination_mgr mgr; + JpegCompressor* compressor; +}; + +JpegCompressor::JpegCompressor() {} + +JpegCompressor::~JpegCompressor() {} + +bool JpegCompressor::CompressImage(const void* image, int width, int height, + int quality, const void* app1Buffer, + unsigned int app1Size) { + if (width % 8 != 0 || height % 2 != 0) { + LOGF(ERROR) << "Image size can not be handled: " << width << "x" << height; + return false; + } + + result_buffer_.clear(); + if (!Encode(image, width, height, quality, app1Buffer, app1Size)) { + return false; + } + LOGF(INFO) << "Compressed JPEG: " << (width * height * 12) / 8 << "[" << width + << "x" << height << "] -> " << result_buffer_.size() << " bytes"; + return true; +} + +const void* JpegCompressor::GetCompressedImagePtr() { + return result_buffer_.data(); +} + +size_t JpegCompressor::GetCompressedImageSize() { + return result_buffer_.size(); +} + +void JpegCompressor::InitDestination(j_compress_ptr cinfo) { + destination_mgr* dest = reinterpret_cast(cinfo->dest); + std::vector& buffer = dest->compressor->result_buffer_; + buffer.resize(kBlockSize); + dest->mgr.next_output_byte = &buffer[0]; + dest->mgr.free_in_buffer = buffer.size(); +} + +boolean JpegCompressor::EmptyOutputBuffer(j_compress_ptr cinfo) { + destination_mgr* dest = reinterpret_cast(cinfo->dest); + std::vector& buffer = dest->compressor->result_buffer_; + size_t oldsize = buffer.size(); + buffer.resize(oldsize + kBlockSize); + dest->mgr.next_output_byte = &buffer[oldsize]; + dest->mgr.free_in_buffer = kBlockSize; + return true; +} + +void JpegCompressor::TerminateDestination(j_compress_ptr cinfo) { + destination_mgr* dest = reinterpret_cast(cinfo->dest); + std::vector& buffer = dest->compressor->result_buffer_; + buffer.resize(buffer.size() - dest->mgr.free_in_buffer); +} + +void JpegCompressor::OutputErrorMessage(j_common_ptr cinfo) { + char buffer[JMSG_LENGTH_MAX]; + + /* Create the message */ + (*cinfo->err->format_message)(cinfo, buffer); + LOGF(ERROR) << buffer; +} + +bool JpegCompressor::Encode(const void* inYuv, int width, int height, + int jpegQuality, const void* app1Buffer, + unsigned int app1Size) { + jpeg_compress_struct cinfo; + jpeg_error_mgr jerr; + + cinfo.err = jpeg_std_error(&jerr); + // Override output_message() to print error log with ALOGE(). + cinfo.err->output_message = &OutputErrorMessage; + jpeg_create_compress(&cinfo); + SetJpegDestination(&cinfo); + + SetJpegCompressStruct(width, height, jpegQuality, &cinfo); + jpeg_start_compress(&cinfo, TRUE); + + if (app1Buffer != nullptr && app1Size > 0) { + jpeg_write_marker(&cinfo, JPEG_APP0 + 1, + static_cast(app1Buffer), app1Size); + } + + if (!Compress(&cinfo, static_cast(inYuv))) { + return false; + } + jpeg_finish_compress(&cinfo); + return true; +} + +void JpegCompressor::SetJpegDestination(jpeg_compress_struct* cinfo) { + destination_mgr* dest = + static_cast((*cinfo->mem->alloc_small)( + (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(destination_mgr))); + dest->compressor = this; + dest->mgr.init_destination = &InitDestination; + dest->mgr.empty_output_buffer = &EmptyOutputBuffer; + dest->mgr.term_destination = &TerminateDestination; + cinfo->dest = reinterpret_cast(dest); +} + +void JpegCompressor::SetJpegCompressStruct(int width, int height, int quality, + jpeg_compress_struct* cinfo) { + cinfo->image_width = width; + cinfo->image_height = height; + cinfo->input_components = 3; + cinfo->in_color_space = JCS_YCbCr; + jpeg_set_defaults(cinfo); + + jpeg_set_quality(cinfo, quality, TRUE); + jpeg_set_colorspace(cinfo, JCS_YCbCr); + cinfo->raw_data_in = TRUE; + cinfo->dct_method = JDCT_IFAST; + + // Configure sampling factors. The sampling factor is JPEG subsampling 420 + // because the source format is YUV420. + cinfo->comp_info[0].h_samp_factor = 2; + cinfo->comp_info[0].v_samp_factor = 2; + cinfo->comp_info[1].h_samp_factor = 1; + cinfo->comp_info[1].v_samp_factor = 1; + cinfo->comp_info[2].h_samp_factor = 1; + cinfo->comp_info[2].v_samp_factor = 1; +} + +bool JpegCompressor::Compress(jpeg_compress_struct* cinfo, const uint8_t* yuv) { + JSAMPROW y[kCompressBatchSize]; + JSAMPROW cb[kCompressBatchSize / 2]; + JSAMPROW cr[kCompressBatchSize / 2]; + JSAMPARRAY planes[3]{y, cb, cr}; + + size_t y_plane_size = cinfo->image_width * cinfo->image_height; + size_t uv_plane_size = y_plane_size / 4; + uint8_t* y_plane = const_cast(yuv); + uint8_t* u_plane = const_cast(yuv + y_plane_size); + uint8_t* v_plane = const_cast(yuv + y_plane_size + uv_plane_size); + std::unique_ptr empty(new uint8_t[cinfo->image_width]); + memset(empty.get(), 0, cinfo->image_width); + + while (cinfo->next_scanline < cinfo->image_height) { + for (int i = 0; i < kCompressBatchSize; ++i) { + size_t scanline = cinfo->next_scanline + i; + if (scanline < cinfo->image_height) { + y[i] = y_plane + scanline * cinfo->image_width; + } else { + y[i] = empty.get(); + } + } + // cb, cr only have half scanlines + for (int i = 0; i < kCompressBatchSize / 2; ++i) { + size_t scanline = cinfo->next_scanline / 2 + i; + if (scanline < cinfo->image_height / 2) { + int offset = scanline * (cinfo->image_width / 2); + cb[i] = u_plane + offset; + cr[i] = v_plane + offset; + } else { + cb[i] = cr[i] = empty.get(); + } + } + + int processed = jpeg_write_raw_data(cinfo, planes, kCompressBatchSize); + if (processed != kCompressBatchSize) { + LOGF(ERROR) << "Number of processed lines does not equal input lines."; + return false; + } + } + return true; +} + +} // namespace arc diff --git a/modules/camera/3_4/arc/jpeg_compressor.h b/modules/camera/3_4/arc/jpeg_compressor.h new file mode 100644 index 00000000..378f3cda --- /dev/null +++ b/modules/camera/3_4/arc/jpeg_compressor.h @@ -0,0 +1,74 @@ +/* + * Copyright 2017 The Chromium OS Authors. All rights reserved. + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef INCLUDE_ARC_JPEG_COMPRESSOR_H_ +#define INCLUDE_ARC_JPEG_COMPRESSOR_H_ + +// We must include cstdio before jpeglib.h. It is a requirement of libjpeg. +#include +#include +#include + +extern "C" { +#include +#include +} + +namespace arc { + +// Encapsulates a converter from YU12 to JPEG format. This class is not +// thread-safe. +class JpegCompressor { + public: + JpegCompressor(); + ~JpegCompressor(); + + // Compresses YU12 image to JPEG format. After calling this method, call + // GetCompressedImagePtr() to get the image. |quality| is the resulted jpeg + // image quality. It ranges from 1 (poorest quality) to 100 (highest quality). + // |app1Buffer| is the buffer of APP1 segment (exif) which will be added to + // the compressed image. Returns false if errors occur during compression. + bool CompressImage(const void* image, int width, int height, int quality, + const void* app1Buffer, unsigned int app1Size); + + // Returns the compressed JPEG buffer pointer. This method must be called only + // after calling CompressImage(). + const void* GetCompressedImagePtr(); + + // Returns the compressed JPEG buffer size. This method must be called only + // after calling CompressImage(). + size_t GetCompressedImageSize(); + + private: + // InitDestination(), EmptyOutputBuffer() and TerminateDestination() are + // callback functions to be passed into jpeg library. + static void InitDestination(j_compress_ptr cinfo); + static boolean EmptyOutputBuffer(j_compress_ptr cinfo); + static void TerminateDestination(j_compress_ptr cinfo); + static void OutputErrorMessage(j_common_ptr cinfo); + + // Returns false if errors occur. + bool Encode(const void* inYuv, int width, int height, int jpegQuality, + const void* app1Buffer, unsigned int app1Size); + void SetJpegDestination(jpeg_compress_struct* cinfo); + void SetJpegCompressStruct(int width, int height, int quality, + jpeg_compress_struct* cinfo); + // Returns false if errors occur. + bool Compress(jpeg_compress_struct* cinfo, const uint8_t* yuv); + + // The block size for encoded jpeg image buffer. + static const int kBlockSize = 16384; + // Process 16 lines of Y and 16 lines of U/V each time. + // We must pass at least 16 scanlines according to libjpeg documentation. + static const int kCompressBatchSize = 16; + + // The buffer that holds the compressed result. + std::vector result_buffer_; +}; + +} // namespace arc + +#endif // INCLUDE_ARC_JPEG_COMPRESSOR_H_ diff --git a/modules/camera/3_4/format_metadata_factory.cpp b/modules/camera/3_4/format_metadata_factory.cpp index a08f9a8b..db03678d 100644 --- a/modules/camera/3_4/format_metadata_factory.cpp +++ b/modules/camera/3_4/format_metadata_factory.cpp @@ -16,6 +16,7 @@ #include "format_metadata_factory.h" +#include "arc/image_processor.h" #include "metadata/array_vector.h" #include "metadata/partial_metadata_factory.h" #include "metadata/property.h" @@ -35,6 +36,7 @@ static int GetHalFormats(const std::shared_ptr& device, HAL_LOGE("Failed to get device formats."); return res; } + for (auto v4l2_format : v4l2_formats) { int32_t hal_format = StreamFormat::V4L2ToHalPixelFormat(v4l2_format); if (hal_format < 0) { @@ -44,21 +46,17 @@ static int GetHalFormats(const std::shared_ptr& device, result_formats->insert(hal_format); } - // In addition to well-defined formats, there may be an - // "Implementation Defined" format chosen by the HAL (in this - // case what that means is managed by the StreamFormat class). - - // Get the V4L2 format for IMPLEMENTATION_DEFINED. - int v4l2_format = StreamFormat::HalToV4L2PixelFormat( - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); - // If it's available, add IMPLEMENTATION_DEFINED to the result set. - if (v4l2_format && v4l2_formats.count(v4l2_format) > 0) { - result_formats->insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); - } - return 0; } +static int FpsRangesCompare(std::array a, + std::array b) { + if (a[1] == b[1]) { + return a[0] > b[0]; + } + return a[1] > b[1]; +} + int AddFormatComponents( std::shared_ptr device, std::insert_iterator insertion_point) { @@ -71,19 +69,39 @@ int AddFormatComponents( return res; } - // Requirements check: need to support YCbCr_420_888, JPEG, - // and "Implementation Defined". + std::set unsupported_hal_formats; if (hal_formats.find(HAL_PIXEL_FORMAT_YCbCr_420_888) == hal_formats.end()) { - HAL_LOGE("YCbCr_420_888 not supported by device."); - return -ENODEV; - } else if (hal_formats.find(HAL_PIXEL_FORMAT_BLOB) == hal_formats.end()) { - HAL_LOGE("JPEG not supported by device."); - return -ENODEV; - } else if (hal_formats.find(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) == - hal_formats.end()) { - HAL_LOGE("HAL implementation defined format not supported by device."); - return -ENODEV; + HAL_LOGW("YCbCr_420_888 (0x%x) not directly supported by device.", + HAL_PIXEL_FORMAT_YCbCr_420_888); + hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888); + unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_YCbCr_420_888); } + if (hal_formats.find(HAL_PIXEL_FORMAT_BLOB) == hal_formats.end()) { + HAL_LOGW("JPEG (0x%x) not directly supported by device.", + HAL_PIXEL_FORMAT_BLOB); + hal_formats.insert(HAL_PIXEL_FORMAT_BLOB); + unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_BLOB); + } + + // As hal_formats is populated by reading and converting V4L2 formats to the + // matching HAL formats, we will never see an implementation defined format in + // the list. We populate it ourselves and map it to a qualified format. If no + // qualified formats exist, this will be the first available format. + hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); + unsupported_hal_formats.insert(HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); + + // Qualified formats are the set of formats supported by this camera that the + // image processor can translate into the YU12 format. We additionally check + // that the conversion from YU12 to the desired hal format is supported. + std::vector qualified_formats; + res = device->GetQualifiedFormats(&qualified_formats); + if (res && unsupported_hal_formats.size() > 1) { + HAL_LOGE( + "Failed to retrieve qualified formats, cannot perform conversions."); + return res; + } + + HAL_LOGI("Supports %d qualified formats.", qualified_formats.size()); // Find sizes and frame/stall durations for all formats. // We also want to find the smallest max frame duration amongst all formats, @@ -96,7 +114,7 @@ int AddFormatComponents( // Stall durations are {format, width, height, duration} (duration in ns). ArrayVector stall_durations; int64_t min_max_frame_duration = std::numeric_limits::max(); - int64_t max_min_frame_duration_yuv = std::numeric_limits::min(); + std::vector> fps_ranges; for (auto hal_format : hal_formats) { // Get the corresponding V4L2 format. uint32_t v4l2_format = StreamFormat::HalToV4L2PixelFormat(hal_format); @@ -105,6 +123,42 @@ int AddFormatComponents( // came from translating a bunch of V4L2 formats above. HAL_LOGE("Couldn't find V4L2 format for HAL format %d", hal_format); return -ENODEV; + } else if (unsupported_hal_formats.find(hal_format) != + unsupported_hal_formats.end()) { + if (hal_format == HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) { + if (qualified_formats.size() != 0) { + v4l2_format = qualified_formats[0]; + } else if (unsupported_hal_formats.size() == 1) { + v4l2_format = StreamFormat::HalToV4L2PixelFormat( + HAL_PIXEL_FORMAT_YCbCr_420_888); + } else { + // No-op. If there are no qualified formats, and implementation + // defined is not the only unsupported format, then other unsupported + // formats will throw an error. + } + HAL_LOGW( + "Implementation-defined format is set to V4L2 pixel format 0x%x", + v4l2_format); + } else if (qualified_formats.size() == 0) { + HAL_LOGE( + "Camera does not support required format: 0x%x, and there are no " + "qualified" + "formats to transform from.", + hal_format); + return -ENODEV; + } else if (!arc::ImageProcessor::SupportsConversion(V4L2_PIX_FMT_YUV420, + v4l2_format)) { + HAL_LOGE( + "The image processor does not support conversion to required " + "format: 0x%x", + hal_format); + return -ENODEV; + } else { + v4l2_format = qualified_formats[0]; + HAL_LOGW( + "Hal format 0x%x will be converted from V4L2 pixel format 0x%x", + hal_format, v4l2_format); + } } // Get the available sizes for this format. @@ -160,39 +214,25 @@ int AddFormatComponents( if (size_max_frame_duration < min_max_frame_duration) { min_max_frame_duration = size_max_frame_duration; } - // We only care about the largest min frame duration - // (smallest max frame rate) for YUV sizes. - if (hal_format == HAL_PIXEL_FORMAT_YCbCr_420_888 && - size_min_frame_duration > max_min_frame_duration_yuv) { - max_min_frame_duration_yuv = size_min_frame_duration; + // ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES will contain all + // the fps ranges for YUV_420_888 only since YUV_420_888 format is + // the default camera format by Android. + if (hal_format == HAL_PIXEL_FORMAT_YCbCr_420_888) { + // Convert from frame durations measured in ns. + // Min, max fps supported by all YUV formats. + const int32_t min_fps = 1000000000 / size_max_frame_duration; + const int32_t max_fps = 1000000000 / size_min_frame_duration; + if (std::find(fps_ranges.begin(), fps_ranges.end(), + std::array{min_fps, max_fps}) == + fps_ranges.end()) { + fps_ranges.push_back({min_fps, max_fps}); + } } } } - // Convert from frame durations measured in ns. - // Min fps supported by all formats. - int32_t min_fps = 1000000000 / min_max_frame_duration; - if (min_fps > 15) { - HAL_LOGE("Minimum FPS %d is larger than HAL max allowable value of 15", - min_fps); - return -ENODEV; - } - // Max fps supported by all YUV formats. - int32_t max_yuv_fps = 1000000000 / max_min_frame_duration_yuv; - // ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES should be at minimum - // {mi, ma}, {ma, ma} where mi and ma are min and max frame rates for - // YUV_420_888. Min should be at most 15. - std::vector> fps_ranges; - fps_ranges.push_back({{min_fps, max_yuv_fps}}); - - std::array video_fps_range; - int32_t video_fps = 30; - if (video_fps >= max_yuv_fps) { - video_fps_range = {{max_yuv_fps, max_yuv_fps}}; - } else { - video_fps_range = {{video_fps, video_fps}}; - } - fps_ranges.push_back(video_fps_range); + // Sort fps ranges in descending order. + std::sort(fps_ranges.begin(), fps_ranges.end(), FpsRangesCompare); // Construct the metadata components. insertion_point = std::make_unique>>( @@ -208,10 +248,9 @@ int AddFormatComponents( // TODO(b/31019725): This should probably not be a NoEffect control. insertion_point = NoEffectMenuControl>( ANDROID_CONTROL_AE_TARGET_FPS_RANGE, - ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, - fps_ranges, - {{CAMERA3_TEMPLATE_VIDEO_RECORD, video_fps_range}, - {OTHER_TEMPLATES, fps_ranges[0]}}); + ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES, fps_ranges, + {{CAMERA3_TEMPLATE_VIDEO_RECORD, fps_ranges.front()}, + {OTHER_TEMPLATES, fps_ranges.back()}}); return 0; } diff --git a/modules/camera/3_4/format_metadata_factory.h b/modules/camera/3_4/format_metadata_factory.h index 4cf5952f..23c1777b 100644 --- a/modules/camera/3_4/format_metadata_factory.h +++ b/modules/camera/3_4/format_metadata_factory.h @@ -17,6 +17,7 @@ #ifndef V4L2_CAMERA_HAL_FORMAT_METADATA_FACTORY_H_ #define V4L2_CAMERA_HAL_FORMAT_METADATA_FACTORY_H_ +#include #include #include #include diff --git a/modules/camera/3_4/format_metadata_factory_test.cpp b/modules/camera/3_4/format_metadata_factory_test.cpp index d37b09f7..fe5d67f5 100644 --- a/modules/camera/3_4/format_metadata_factory_test.cpp +++ b/modules/camera/3_4/format_metadata_factory_test.cpp @@ -46,10 +46,12 @@ class FormatMetadataFactoryTest : public Test { }; TEST_F(FormatMetadataFactoryTest, GetFormatMetadata) { - std::set formats{V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420}; + std::set formats{V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420, + V4L2_PIX_FMT_YUYV}; std::map>> sizes{ {V4L2_PIX_FMT_JPEG, {{{10, 20}}, {{30, 60}}, {{120, 240}}}}, - {V4L2_PIX_FMT_YUV420, {{{1, 2}}, {{3, 6}}, {{12, 24}}}}}; + {V4L2_PIX_FMT_YUV420, {{{1, 2}}, {{3, 6}}, {{12, 24}}}}, + {V4L2_PIX_FMT_YUYV, {{{20, 40}}, {{80, 160}}, {{320, 640}}}}}; // These need to be on the correct order of magnitude, // as there is a check for min fps > 15. std::map, std::array>> @@ -60,19 +62,24 @@ TEST_F(FormatMetadataFactoryTest, GetFormatMetadata) { {V4L2_PIX_FMT_YUV420, {{{{1, 2}}, {{10000000000, 20000000000}}}, {{{3, 6}}, {{11000000000, 21000000000}}}, - {{{12, 24}}, {{10500000000, 19000000000}}}}}}; + {{{12, 24}}, {{10500000000, 19000000000}}}}}, + {V4L2_PIX_FMT_YUYV, + {{{{20, 40}}, {{11000000000, 22000000000}}}, + {{{80, 160}}, {{13000000000, 25000000000}}}, + {{{320, 640}}, {{10100000000, 19000000000}}}}}}; + // The camera must report at least one qualified format. + std::vector qualified_formats = {V4L2_PIX_FMT_YUYV}; // Device must support IMPLEMENTATION_DEFINED (as well as JPEG & YUV). - // Just duplicate the values from another format. - uint32_t imp_defined_format = StreamFormat::HalToV4L2PixelFormat( - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); - formats.insert(imp_defined_format); - sizes[imp_defined_format] = sizes[V4L2_PIX_FMT_YUV420]; - durations[imp_defined_format] = durations[V4L2_PIX_FMT_YUV420]; + // For USB cameras, we assume that this format will not be present, and it + // will default to a qualified format or one of the other required formats. EXPECT_CALL(*mock_device_, GetFormats(_)) .WillOnce(DoAll(SetArgPointee<0>(formats), Return(0))); + EXPECT_CALL(*mock_device_, GetQualifiedFormats(_)) + .WillOnce(DoAll(SetArgPointee<0>(qualified_formats), Return(0))); + for (auto format : formats) { std::set> format_sizes = sizes[format]; EXPECT_CALL(*mock_device_, GetFormatFrameSizes(format, _)) @@ -94,7 +101,7 @@ TEST_F(FormatMetadataFactoryTest, GetFormatMetadata) { for (auto& component : components) { android::CameraMetadata metadata; component->PopulateStaticFields(&metadata); - ASSERT_EQ(metadata.entryCount(), 1); + ASSERT_EQ(metadata.entryCount(), 1u); int32_t tag = component->StaticTags()[0]; switch (tag) { case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS: // Fall through. @@ -119,39 +126,71 @@ TEST_F(FormatMetadataFactoryTest, GetFormatMetadata) { } } -TEST_F(FormatMetadataFactoryTest, GetFormatMetadataMissingJpeg) { - uint32_t imp_defined_format = StreamFormat::HalToV4L2PixelFormat( - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); - std::set formats{V4L2_PIX_FMT_YUV420, imp_defined_format}; - EXPECT_CALL(*mock_device_, GetFormats(_)) - .WillOnce(DoAll(SetArgPointee<0>(formats), Return(0))); - PartialMetadataSet components; - ASSERT_EQ(AddFormatComponents(mock_device_, - std::inserter(components, components.end())), - -ENODEV); -} +TEST_F(FormatMetadataFactoryTest, GetFormatMetadataMissingRequired) { + std::set formats{V4L2_PIX_FMT_YUYV}; + std::map>> sizes{ + {V4L2_PIX_FMT_YUYV, {{{640, 480}}, {{320, 240}}}}}; + std::map, std::array>> + durations{{V4L2_PIX_FMT_YUYV, + {{{{640, 480}}, {{100000000, 200000000}}}, + {{{320, 240}}, {{100000000, 200000000}}}}}}; -TEST_F(FormatMetadataFactoryTest, GetFormatMetadataMissingYuv) { - uint32_t imp_defined_format = StreamFormat::HalToV4L2PixelFormat( - HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED); - std::set formats{V4L2_PIX_FMT_JPEG, imp_defined_format}; EXPECT_CALL(*mock_device_, GetFormats(_)) .WillOnce(DoAll(SetArgPointee<0>(formats), Return(0))); - PartialMetadataSet components; - ASSERT_EQ(AddFormatComponents(mock_device_, - std::inserter(components, components.end())), - -ENODEV); -} + // If a qualified format is present, we expect that required fields are + // populated as if they are supported. + std::vector qualified_formats = {V4L2_PIX_FMT_YUYV}; -TEST_F(FormatMetadataFactoryTest, - GetFormatMetadataMissingImplementationDefined) { - std::set formats{V4L2_PIX_FMT_JPEG, V4L2_PIX_FMT_YUV420}; - EXPECT_CALL(*mock_device_, GetFormats(_)) - .WillOnce(DoAll(SetArgPointee<0>(formats), Return(0))); + EXPECT_CALL(*mock_device_, GetQualifiedFormats(_)) + .WillOnce(DoAll(SetArgPointee<0>(qualified_formats), Return(0))); + + for (auto format : formats) { + std::set> format_sizes = sizes[format]; + EXPECT_CALL(*mock_device_, GetFormatFrameSizes(format, _)) + .Times(AtLeast(1)) + .WillRepeatedly(DoAll(SetArgPointee<1>(format_sizes), Return(0))); + for (auto size : format_sizes) { + EXPECT_CALL(*mock_device_, GetFormatFrameDurationRange(format, size, _)) + .Times(AtLeast(1)) + .WillRepeatedly( + DoAll(SetArgPointee<2>(durations[format][size]), Return(0))); + } + } + + // Check that all required formats are present. PartialMetadataSet components; ASSERT_EQ(AddFormatComponents(mock_device_, std::inserter(components, components.end())), - -ENODEV); + 0); + + std::vector> target_fps_ranges{{{5, 10}}, {{10, 10}}}; + for (auto& component : components) { + android::CameraMetadata metadata; + component->PopulateStaticFields(&metadata); + ASSERT_EQ(metadata.entryCount(), 1u); + int32_t tag = component->StaticTags()[0]; + switch (tag) { + case ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS: // Fall through. + case ANDROID_SCALER_AVAILABLE_MIN_FRAME_DURATIONS: // Fall through. + case ANDROID_SCALER_AVAILABLE_STALL_DURATIONS: // Fall through. + // Two sizes per format, four elements per config. + // # formats + 3 for YUV420, JPEG, IMPLEMENTATION_DEFINED. + ExpectMetadataTagCount(metadata, tag, (formats.size() + 3) * 2 * 4); + break; + case ANDROID_SENSOR_INFO_MAX_FRAME_DURATION: + // The lowest max duration from above. + ExpectMetadataEq(metadata, tag, 200000000); + break; + case ANDROID_CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES: + // 2 ranges ({min, max} and {max, max}), each with a min and max. + ExpectMetadataTagCount(metadata, tag, 4); + ExpectMetadataEq(metadata, tag, target_fps_ranges); + break; + default: + FAIL() << "Unexpected component created."; + break; + } + } } } // namespace v4l2_camera_hal diff --git a/modules/camera/3_4/metadata/control_test.cpp b/modules/camera/3_4/metadata/control_test.cpp index f76376cc..6284330e 100644 --- a/modules/camera/3_4/metadata/control_test.cpp +++ b/modules/camera/3_4/metadata/control_test.cpp @@ -64,15 +64,15 @@ class ControlTest : public Test { virtual void ExpectTags() { if (use_options_ && report_options_) { - ASSERT_EQ(control_->StaticTags().size(), 1); + ASSERT_EQ(control_->StaticTags().size(), 1u); EXPECT_EQ(control_->StaticTags()[0], options_tag_); } else { EXPECT_TRUE(control_->StaticTags().empty()); } // Controls use the same delgate, and thus tag, for getting and setting. - ASSERT_EQ(control_->ControlTags().size(), 1); + ASSERT_EQ(control_->ControlTags().size(), 1u); EXPECT_EQ(control_->ControlTags()[0], delegate_tag_); - ASSERT_EQ(control_->DynamicTags().size(), 1); + ASSERT_EQ(control_->DynamicTags().size(), 1u); EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_); } @@ -81,10 +81,10 @@ class ControlTest : public Test { android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0); if (use_options_ && report_options_) { - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, options_tag_, options); } else { - EXPECT_EQ(metadata.entryCount(), 0); + EXPECT_EQ(metadata.entryCount(), 0u); // Shouldn't be expecting any options. EXPECT_TRUE(options.empty()); } @@ -93,7 +93,7 @@ class ControlTest : public Test { virtual void ExpectValue(uint8_t value) { android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0); - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, delegate_tag_, value); } diff --git a/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp b/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp index 9ca3a383..3537ed24 100644 --- a/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp +++ b/modules/camera/3_4/metadata/partial_metadata_factory_test.cpp @@ -44,11 +44,11 @@ class PartialMetadataFactoryTest : public Test { } virtual void ExpectControlTags() { - ASSERT_EQ(control_->StaticTags().size(), 1); + ASSERT_EQ(control_->StaticTags().size(), 1u); EXPECT_EQ(control_->StaticTags()[0], options_tag_); - ASSERT_EQ(control_->ControlTags().size(), 1); + ASSERT_EQ(control_->ControlTags().size(), 1u); EXPECT_EQ(control_->ControlTags()[0], delegate_tag_); - ASSERT_EQ(control_->DynamicTags().size(), 1); + ASSERT_EQ(control_->DynamicTags().size(), 1u); EXPECT_EQ(control_->DynamicTags()[0], delegate_tag_); } @@ -56,14 +56,14 @@ class PartialMetadataFactoryTest : public Test { // Options should be available. android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateStaticFields(&metadata), 0); - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, options_tag_, options); } virtual void ExpectControlValue(uint8_t value) { android::CameraMetadata metadata; ASSERT_EQ(control_->PopulateDynamicFields(&metadata), 0); - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, delegate_tag_, value); } @@ -84,14 +84,14 @@ TEST_F(PartialMetadataFactoryTest, FixedState) { uint8_t value = 13; std::unique_ptr> state = FixedState(delegate_tag_, value); - ASSERT_EQ(state->StaticTags().size(), 0); - ASSERT_EQ(state->ControlTags().size(), 0); - ASSERT_EQ(state->DynamicTags().size(), 1); + ASSERT_EQ(state->StaticTags().size(), 0u); + ASSERT_EQ(state->ControlTags().size(), 0u); + ASSERT_EQ(state->DynamicTags().size(), 1u); EXPECT_EQ(state->DynamicTags()[0], delegate_tag_); android::CameraMetadata metadata; ASSERT_EQ(state->PopulateDynamicFields(&metadata), 0); - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, delegate_tag_, value); } diff --git a/modules/camera/3_4/metadata/property_test.cpp b/modules/camera/3_4/metadata/property_test.cpp index 8e947ea3..80f8eb8d 100644 --- a/modules/camera/3_4/metadata/property_test.cpp +++ b/modules/camera/3_4/metadata/property_test.cpp @@ -49,9 +49,9 @@ TEST_F(PropertyTest, Tags) { Property property(int_tag_, 1); // Should have only the single tag it was constructed with. - EXPECT_EQ(property.ControlTags().size(), 0); - EXPECT_EQ(property.DynamicTags().size(), 0); - ASSERT_EQ(property.StaticTags().size(), 1); + EXPECT_EQ(property.ControlTags().size(), 0u); + EXPECT_EQ(property.DynamicTags().size(), 0u); + ASSERT_EQ(property.StaticTags().size(), 1u); // The macro doesn't like the int_tag_ variable being passed in directly. int32_t expected_tag = int_tag_; EXPECT_EQ(property.StaticTags()[0], expected_tag); @@ -68,7 +68,7 @@ TEST_F(PropertyTest, PopulateStaticSingleNumber) { // Check the results. // Should only have added 1 entry. - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); // Should have added the right entry. ExpectMetadataEq(metadata, int_tag_, data); } @@ -86,7 +86,7 @@ TEST_F(PropertyTest, PopulateStaticVector) { // Check the results. // Should only have added 1 entry. - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); // Should have added the right entry. ExpectMetadataEq(metadata, float_tag_, data); } @@ -102,7 +102,7 @@ TEST_F(PropertyTest, PopulateStaticArray) { // Check the results. // Should only have added 1 entry. - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); // Should have added the right entry. ExpectMetadataEq(metadata, float_tag_, data); } @@ -120,7 +120,7 @@ TEST_F(PropertyTest, PopulateStaticArrayVector) { // Check the results. // Should only have added 1 entry. - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); // Should have added the right entry. ExpectMetadataEq(metadata, byte_tag_, data); } diff --git a/modules/camera/3_4/metadata/state_test.cpp b/modules/camera/3_4/metadata/state_test.cpp index 5c308bc9..ecc1d154 100644 --- a/modules/camera/3_4/metadata/state_test.cpp +++ b/modules/camera/3_4/metadata/state_test.cpp @@ -59,7 +59,7 @@ TEST_F(StateTest, Tags) { PrepareState(); EXPECT_TRUE(state_->StaticTags().empty()); EXPECT_TRUE(state_->ControlTags().empty()); - ASSERT_EQ(state_->DynamicTags().size(), 1); + ASSERT_EQ(state_->DynamicTags().size(), 1u); EXPECT_EQ(state_->DynamicTags()[0], tag_); } @@ -79,7 +79,7 @@ TEST_F(StateTest, PopulateDynamic) { android::CameraMetadata metadata; ASSERT_EQ(state_->PopulateDynamicFields(&metadata), 0); - EXPECT_EQ(metadata.entryCount(), 1); + EXPECT_EQ(metadata.entryCount(), 1u); ExpectMetadataEq(metadata, tag_, expected); } diff --git a/modules/camera/3_4/metadata/test_common.h b/modules/camera/3_4/metadata/test_common.h index 489990ff..42e44f0b 100644 --- a/modules/camera/3_4/metadata/test_common.h +++ b/modules/camera/3_4/metadata/test_common.h @@ -80,9 +80,9 @@ static void ExpectMetadataEq(const android::CameraMetadata& metadata, // Vector of arrays. template -static int ExpectMetadataEq(const android::CameraMetadata& metadata, - int32_t tag, - const std::vector>& expected) { +static void ExpectMetadataEq(const android::CameraMetadata& metadata, + int32_t tag, + const std::vector>& expected) { // Convert to array vector so we know all the elements are contiguous. ArrayVector array_vector; for (const auto& array : expected) { diff --git a/modules/camera/3_4/stream_format.cpp b/modules/camera/3_4/stream_format.cpp index 70900abb..5f35e425 100644 --- a/modules/camera/3_4/stream_format.cpp +++ b/modules/camera/3_4/stream_format.cpp @@ -20,10 +20,21 @@ #include +#include "arc/image_processor.h" #include "common.h" namespace v4l2_camera_hal { +using arc::SupportedFormat; +using arc::SupportedFormats; + +static const std::vector GetSupportedFourCCs() { + // The preference of supported fourccs in the list is from high to low. + static const std::vector kSupportedFourCCs = {V4L2_PIX_FMT_YUYV, + V4L2_PIX_FMT_MJPEG}; + return kSupportedFourCCs; +} + StreamFormat::StreamFormat(int format, uint32_t width, uint32_t height) // TODO(b/30000211): multiplanar support. : type_(V4L2_BUF_TYPE_VIDEO_CAPTURE), @@ -42,6 +53,14 @@ StreamFormat::StreamFormat(const v4l2_format& format) bytes_per_line_(format.fmt.pix.bytesperline), min_buffer_size_(format.fmt.pix.sizeimage) {} +StreamFormat::StreamFormat(const arc::SupportedFormat& format) + : type_(V4L2_BUF_TYPE_VIDEO_CAPTURE), + v4l2_pixel_format_(format.fourcc), + width_(format.width), + height_(format.height), + bytes_per_line_(0), + min_buffer_size_(0) {} + void StreamFormat::FillFormatRequest(v4l2_format* format) const { memset(format, 0, sizeof(*format)); format->type = type_; @@ -57,7 +76,7 @@ FormatCategory StreamFormat::Category() const { case V4L2_PIX_FMT_JPEG: return kFormatCategoryStalling; case V4L2_PIX_FMT_YUV420: // Fall through. - case V4L2_PIX_FMT_RGB24: + case V4L2_PIX_FMT_BGR32: return kFormatCategoryNonStalling; default: // Note: currently no supported RAW formats. @@ -79,47 +98,127 @@ bool StreamFormat::operator!=(const StreamFormat& other) const { int StreamFormat::V4L2ToHalPixelFormat(uint32_t v4l2_pixel_format) { // Translate V4L2 format to HAL format. - int hal_pixel_format = -1; switch (v4l2_pixel_format) { + case V4L2_PIX_FMT_BGR32: + return HAL_PIXEL_FORMAT_RGBA_8888; case V4L2_PIX_FMT_JPEG: - hal_pixel_format = HAL_PIXEL_FORMAT_BLOB; - break; + return HAL_PIXEL_FORMAT_BLOB; + case V4L2_PIX_FMT_NV21: + return HAL_PIXEL_FORMAT_YCrCb_420_SP; case V4L2_PIX_FMT_YUV420: - hal_pixel_format = HAL_PIXEL_FORMAT_YCbCr_420_888; - break; - case V4L2_PIX_FMT_RGB24: - hal_pixel_format = HAL_PIXEL_FORMAT_RGBA_8888; - break; + return HAL_PIXEL_FORMAT_YCbCr_420_888; + case V4L2_PIX_FMT_YUYV: + return HAL_PIXEL_FORMAT_YCbCr_422_I; + case V4L2_PIX_FMT_YVU420: + return HAL_PIXEL_FORMAT_YV12; default: // Unrecognized format. HAL_LOGV("Unrecognized v4l2 pixel format %u", v4l2_pixel_format); break; } - return hal_pixel_format; + return -1; } uint32_t StreamFormat::HalToV4L2PixelFormat(int hal_pixel_format) { - // Translate HAL format to V4L2 format. - uint32_t v4l2_pixel_format = 0; switch (hal_pixel_format) { - case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: // fall-through. - case HAL_PIXEL_FORMAT_RGBA_8888: - // Should be RGB32, but RPi doesn't support that. - // For now we accept that the colors will be off. - v4l2_pixel_format = V4L2_PIX_FMT_RGB24; - break; - case HAL_PIXEL_FORMAT_YCbCr_420_888: - v4l2_pixel_format = V4L2_PIX_FMT_YUV420; - break; case HAL_PIXEL_FORMAT_BLOB: - v4l2_pixel_format = V4L2_PIX_FMT_JPEG; - break; + return V4L2_PIX_FMT_JPEG; + case HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED: // Fall-through + case HAL_PIXEL_FORMAT_RGBA_8888: + return V4L2_PIX_FMT_BGR32; + case HAL_PIXEL_FORMAT_YCbCr_420_888: + // This is a flexible YUV format that depends on platform. Different + // platform may have different format. It can be YVU420 or NV12. Now we + // return YVU420 first. + // TODO(): call drm_drv.get_fourcc() to get correct format. + return V4L2_PIX_FMT_YUV420; + case HAL_PIXEL_FORMAT_YCbCr_422_I: + return V4L2_PIX_FMT_YUYV; + case HAL_PIXEL_FORMAT_YCrCb_420_SP: + return V4L2_PIX_FMT_NV21; + case HAL_PIXEL_FORMAT_YV12: + return V4L2_PIX_FMT_YVU420; default: - // Unrecognized format. - HAL_LOGV("Unrecognized HAL pixel format %d", hal_pixel_format); + HAL_LOGV("Pixel format 0x%x is unsupported.", hal_pixel_format); break; } - return v4l2_pixel_format; + return -1; +} + +// Copy the qualified format into out_format and return true if there is a +// proper and fitting format in the given format lists. +bool StreamFormat::FindBestFitFormat(const SupportedFormats& supported_formats, + const SupportedFormats& qualified_formats, + uint32_t fourcc, uint32_t width, + uint32_t height, + SupportedFormat* out_format) { + // Match exact format and resolution if possible. + for (const auto& format : supported_formats) { + if (format.fourcc == fourcc && format.width == width && + format.height == height) { + if (out_format != NULL) { + *out_format = format; + } + return true; + } + } + // All conversions will be done through CachedFrame for now, which will + // immediately convert the qualified format into YU12 (YUV420). We check + // here that the conversion between YU12 and |fourcc| is supported. + if (!arc::ImageProcessor::SupportsConversion(V4L2_PIX_FMT_YUV420, fourcc)) { + HAL_LOGE("Conversion between YU12 and 0x%x not supported.", fourcc); + return false; + } + + // Choose the qualified format with a matching resolution. + for (const auto& format : qualified_formats) { + if (format.width == width && format.height == height) { + if (out_format != NULL) { + *out_format = format; + } + return true; + } + } + return false; +} + +// Copy corresponding format into out_format and return true by matching +// resolution |width|x|height| in |formats|. +bool StreamFormat::FindFormatByResolution(const SupportedFormats& formats, + uint32_t width, uint32_t height, + SupportedFormat* out_format) { + for (const auto& format : formats) { + if (format.width == width && format.height == height) { + if (out_format != NULL) { + *out_format = format; + } + return true; + } + } + return false; +} + +SupportedFormats StreamFormat::GetQualifiedFormats( + const SupportedFormats& supported_formats) { + // The preference of supported fourccs in the list is from high to low. + const std::vector supported_fourccs = GetSupportedFourCCs(); + SupportedFormats qualified_formats; + for (const auto& supported_fourcc : supported_fourccs) { + for (const auto& supported_format : supported_formats) { + if (supported_format.fourcc != supported_fourcc) { + continue; + } + + // Skip if |qualified_formats| already has the same resolution with a more + // preferred fourcc. + if (FindFormatByResolution(qualified_formats, supported_format.width, + supported_format.height, NULL)) { + continue; + } + qualified_formats.push_back(supported_format); + } + } + return qualified_formats; } } // namespace v4l2_camera_hal diff --git a/modules/camera/3_4/stream_format.h b/modules/camera/3_4/stream_format.h index 66c59659..720e3800 100644 --- a/modules/camera/3_4/stream_format.h +++ b/modules/camera/3_4/stream_format.h @@ -21,6 +21,7 @@ #include +#include "arc/common_types.h" #include "common.h" namespace v4l2_camera_hal { @@ -36,6 +37,7 @@ class StreamFormat { public: StreamFormat(int format, uint32_t width, uint32_t height); StreamFormat(const v4l2_format& format); + StreamFormat(const arc::SupportedFormat& format); virtual ~StreamFormat() = default; // Only uint32_t members, use default generated copy and assign. @@ -44,6 +46,9 @@ class StreamFormat { // Accessors. inline uint32_t type() const { return type_; }; + inline uint32_t width() const { return width_; }; + inline uint32_t height() const { return height_; }; + inline uint32_t v4l2_pixel_format() const { return v4l2_pixel_format_; } inline uint32_t bytes_per_line() const { return bytes_per_line_; }; bool operator==(const StreamFormat& other) const; @@ -55,6 +60,18 @@ class StreamFormat { // Returns -1 for unrecognized. static int V4L2ToHalPixelFormat(uint32_t v4l2_pixel_format); + // ARC++ SupportedFormat Helpers + static bool FindBestFitFormat(const arc::SupportedFormats& supported_formats, + const arc::SupportedFormats& qualified_formats, + uint32_t fourcc, uint32_t width, + uint32_t height, + arc::SupportedFormat* out_format); + static bool FindFormatByResolution(const arc::SupportedFormats& formats, + uint32_t width, uint32_t height, + arc::SupportedFormat* out_format); + static arc::SupportedFormats GetQualifiedFormats( + const arc::SupportedFormats& supported_formats); + private: uint32_t type_; uint32_t v4l2_pixel_format_; diff --git a/modules/camera/3_4/v4l2_camera.cpp b/modules/camera/3_4/v4l2_camera.cpp index 22406c92..98b80622 100644 --- a/modules/camera/3_4/v4l2_camera.cpp +++ b/modules/camera/3_4/v4l2_camera.cpp @@ -123,16 +123,7 @@ void V4L2Camera::disconnect() { int V4L2Camera::flushBuffers() { HAL_LOG_ENTER(); - - int res = device_->StreamOff(); - - // This is not strictly necessary, but prevents a buildup of aborted - // requests in the in_flight_ map. These should be cleared - // whenever the stream is turned off. - std::lock_guard guard(in_flight_lock_); - in_flight_.clear(); - - return res; + return device_->StreamOff(); } int V4L2Camera::initStaticInfo(android::CameraMetadata* out) { @@ -262,55 +253,41 @@ bool V4L2Camera::enqueueRequestBuffers() { } // Actually enqueue the buffer for capture. - { - std::lock_guard guard(in_flight_lock_); - - uint32_t index; - res = device_->EnqueueBuffer(&request->output_buffers[0], &index); - if (res) { - HAL_LOGE("Device failed to enqueue buffer."); - completeRequest(request, res); - return true; - } - - // Make sure the stream is on (no effect if already on). - res = device_->StreamOn(); - if (res) { - HAL_LOGE("Device failed to turn on stream."); - // Don't really want to send an error for only the request here, - // since this is a full device error. - // TODO: Should trigger full flush. - return true; - } - - // Note: the request should be dequeued/flushed from the device - // before removal from in_flight_. - in_flight_.emplace(index, request); - buffers_in_flight_.notify_one(); + res = device_->EnqueueRequest(request); + if (res) { + HAL_LOGE("Device failed to enqueue buffer."); + completeRequest(request, res); + return true; } + // Make sure the stream is on (no effect if already on). + res = device_->StreamOn(); + if (res) { + HAL_LOGE("Device failed to turn on stream."); + // Don't really want to send an error for only the request here, + // since this is a full device error. + // TODO: Should trigger full flush. + return true; + } + + std::unique_lock lock(in_flight_lock_); + in_flight_buffer_count_++; + buffers_in_flight_.notify_one(); return true; } bool V4L2Camera::dequeueRequestBuffers() { // Dequeue a buffer. - uint32_t result_index; + std::shared_ptr request; int res; { - std::lock_guard guard(in_flight_lock_); - res = device_->DequeueBuffer(&result_index); + std::unique_lock lock(in_flight_lock_); + res = device_->DequeueRequest(&request); if (!res) { - // Find the associated request and complete it. - auto index_request = in_flight_.find(result_index); - if (index_request != in_flight_.end()) { - completeRequest(index_request->second, 0); - in_flight_.erase(index_request); - } else { - HAL_LOGW( - "Dequeued non in-flight buffer index %d. " - "This buffer may have been flushed from the HAL but not the device.", - index_request->first); + if (request) { + completeRequest(request, res); + in_flight_buffer_count_--; } return true; } @@ -320,7 +297,7 @@ bool V4L2Camera::dequeueRequestBuffers() { // EAGAIN just means nothing to dequeue right now. // Wait until something is available before looping again. std::unique_lock lock(in_flight_lock_); - while (in_flight_.empty()) { + while (in_flight_buffer_count_ == 0) { buffers_in_flight_.wait(lock); } } else { @@ -350,10 +327,11 @@ int V4L2Camera::setupStreams(camera3_stream_configuration_t* stream_config) { std::lock_guard guard(in_flight_lock_); // The framework should be enforcing this, but doesn't hurt to be safe. - if (!in_flight_.empty()) { + if (device_->GetInFlightBufferCount() != 0) { HAL_LOGE("Can't set device format while frames are in flight."); return -EINVAL; } + in_flight_buffer_count_ = 0; // stream_config should have been validated; assume at least 1 stream. camera3_stream_t* stream = stream_config->streams[0]; diff --git a/modules/camera/3_4/v4l2_camera.h b/modules/camera/3_4/v4l2_camera.h index 1db8d40c..fc2adb3e 100644 --- a/modules/camera/3_4/v4l2_camera.h +++ b/modules/camera/3_4/v4l2_camera.h @@ -99,9 +99,7 @@ class V4L2Camera : public default_camera_hal::Camera { std::queue> request_queue_; std::mutex in_flight_lock_; - // Maps buffer index : request. - std::map> - in_flight_; + uint32_t in_flight_buffer_count_; // Threads require holding an Android strong pointer. android::sp buffer_enqueuer_; android::sp buffer_dequeuer_; diff --git a/modules/camera/3_4/v4l2_gralloc.cpp b/modules/camera/3_4/v4l2_gralloc.cpp deleted file mode 100644 index 2fcef355..00000000 --- a/modules/camera/3_4/v4l2_gralloc.cpp +++ /dev/null @@ -1,348 +0,0 @@ -/* - * 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. - */ - -#include "v4l2_gralloc.h" - -#include - -#include - -#include -#include -#include - -#include "common.h" -#include "stream_format.h" - -namespace v4l2_camera_hal { - -// Copy |height| lines from |src| to |dest|, -// where |src| and |dest| may have different line lengths. -void copyWithPadding(uint8_t* dest, - const uint8_t* src, - size_t dest_stride, - size_t src_stride, - size_t height) { - size_t copy_stride = dest_stride; - if (copy_stride > src_stride) { - // Adding padding, not reducing. 0 out the extra memory. - memset(dest, 0, src_stride * height); - copy_stride = src_stride; - } - uint8_t* dest_line_start = dest; - const uint8_t* src_line_start = src; - for (size_t row = 0; row < height; - ++row, dest_line_start += dest_stride, src_line_start += src_stride) { - memcpy(dest_line_start, src_line_start, copy_stride); - } -} - -V4L2Gralloc* V4L2Gralloc::NewV4L2Gralloc() { - // Initialize and check the gralloc module. - const hw_module_t* module = nullptr; - int res = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module); - if (res || !module) { - HAL_LOGE("Couldn't get gralloc module."); - return nullptr; - } - const gralloc_module_t* gralloc = - reinterpret_cast(module); - - // This class only supports Gralloc v0, not Gralloc V1. - if (gralloc->common.module_api_version > GRALLOC_MODULE_API_VERSION_0_3) { - HAL_LOGE( - "Invalid gralloc version %x. Only 0.3 (%x) " - "and below are supported by this HAL.", - gralloc->common.module_api_version, - GRALLOC_MODULE_API_VERSION_0_3); - return nullptr; - } - - return new V4L2Gralloc(gralloc); -} - -// Private. As checked by above factory, module will be non-null -// and a supported version. -V4L2Gralloc::V4L2Gralloc(const gralloc_module_t* module) : mModule(module) {} - -V4L2Gralloc::~V4L2Gralloc() { - // Unlock buffers that are still locked. - unlockAllBuffers(); -} - -int V4L2Gralloc::lock(const camera3_stream_buffer_t* camera_buffer, - uint32_t bytes_per_line, - v4l2_buffer* device_buffer) { - // Lock the camera buffer (varies depending on if the buffer is YUV or not). - std::unique_ptr buffer_data( - new BufferData{camera_buffer, nullptr, bytes_per_line}); - buffer_handle_t buffer = *camera_buffer->buffer; - void* data; - camera3_stream_t* stream = camera_buffer->stream; - int ret = 0; - switch (StreamFormat::HalToV4L2PixelFormat(stream->format)) { - // TODO(b/30119452): support more YCbCr formats. - case V4L2_PIX_FMT_YUV420: - android_ycbcr yuv_data; - ret = mModule->lock_ycbcr(mModule, - buffer, - stream->usage, - 0, - 0, - stream->width, - stream->height, - &yuv_data); - if (ret) { - HAL_LOGE("Failed to lock ycbcr buffer: %d", ret); - return ret; - } - - // Check if gralloc format matches v4l2 format - // (same padding, not interleaved, contiguous). - if (yuv_data.ystride == bytes_per_line && - yuv_data.cstride == bytes_per_line / 2 && yuv_data.chroma_step == 1 && - (reinterpret_cast(yuv_data.cb) == - reinterpret_cast(yuv_data.y) + - (stream->height * yuv_data.ystride)) && - (reinterpret_cast(yuv_data.cr) == - reinterpret_cast(yuv_data.cb) + - (stream->height / 2 * yuv_data.cstride))) { - // If so, great, point to the beginning. - data = yuv_data.y; - } else { - // If not, allocate a contiguous buffer of appropriate size - // (to be transformed back upon unlock). - data = new uint8_t[device_buffer->length]; - // Make a dynamically-allocated copy of yuv_data, - // since it will be needed at transform time. - buffer_data->transform_dest.reset(new android_ycbcr(yuv_data)); - } - break; - case V4L2_PIX_FMT_JPEG: - // Jpeg buffers are just contiguous blobs; lock length * 1. - ret = mModule->lock(mModule, - buffer, - stream->usage, - 0, - 0, - device_buffer->length, - 1, - &data); - if (ret) { - HAL_LOGE("Failed to lock jpeg buffer: %d", ret); - return ret; - } - break; - case V4L2_PIX_FMT_RGB24: // Fall-through. - case V4L2_PIX_FMT_BGR32: // Fall-through. - case V4L2_PIX_FMT_RGB32: - // RGB formats have nice agreed upon representation. Unless using android - // flex formats. - ret = mModule->lock(mModule, - buffer, - stream->usage, - 0, - 0, - stream->width, - stream->height, - &data); - if (ret) { - HAL_LOGE("Failed to lock RGB buffer: %d", ret); - return ret; - } - break; - default: - return -EINVAL; - } - - if (!data) { - ALOGE("Gralloc lock returned null ptr"); - return -ENODEV; - } - - // Set up the device buffer. - static_assert(sizeof(unsigned long) >= sizeof(void*), - "void* must be able to fit in the v4l2_buffer m.userptr " - "field (unsigned long) for this code to work"); - device_buffer->m.userptr = reinterpret_cast(data); - - // Note the mapping of data:buffer info for when unlock is called. - mBufferMap.emplace(data, buffer_data.release()); - - return 0; -} - -int V4L2Gralloc::unlock(const v4l2_buffer* device_buffer) { - // TODO(b/30000211): support multi-planar data (video_capture_mplane). - if (device_buffer->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - return -EINVAL; - } - - void* data = reinterpret_cast(device_buffer->m.userptr); - - // Find and pop the matching entry in the map. - auto map_entry = mBufferMap.find(data); - if (map_entry == mBufferMap.end()) { - HAL_LOGE("No matching buffer for data at %p", data); - return -EINVAL; - } - std::unique_ptr buffer_data(map_entry->second); - mBufferMap.erase(map_entry); - - const camera3_stream_buffer_t* camera_buffer = buffer_data->camera_buffer; - const buffer_handle_t buffer = *camera_buffer->buffer; - - if (StreamFormat::HalToV4L2PixelFormat(camera_buffer->stream->format) == V4L2_PIX_FMT_RGB24) { - // Convert RGB24 to RGB32. - size_t rgb_size = camera_buffer->stream->width * camera_buffer->stream->height; - uint8_t* tail_rgb24 = (uint8_t*)data + 3 * rgb_size - 1; - uint8_t* tail_rgb32 = (uint8_t*)data + 4 * rgb_size - 1; - for (int i = 0; i < rgb_size; i++) { - *(tail_rgb32--) = 0xff; - *(tail_rgb32--) = *(tail_rgb24--); - *(tail_rgb32--) = *(tail_rgb24--); - *(tail_rgb32--) = *(tail_rgb24--); - } - } - - // Check for transform. - if (buffer_data->transform_dest) { - HAL_LOGV("Transforming V4L2 YUV to gralloc YUV."); - // In this case data was allocated by this class, put it in a unique_ptr - // to ensure it gets cleaned up no matter which way this function exits. - std::unique_ptr data_cleanup(reinterpret_cast(data)); - - uint32_t bytes_per_line = buffer_data->v4l2_bytes_per_line; - android_ycbcr* yuv_data = buffer_data->transform_dest.get(); - - // Should only occur in error situations. - if (device_buffer->bytesused == 0) { - return -EINVAL; - } - - // Transform V4L2 to Gralloc, copying each plane to the correct place, - // adjusting padding, and interleaving if necessary. - uint32_t height = camera_buffer->stream->height; - // Y data first. - size_t y_len = bytes_per_line * height; - if (yuv_data->ystride == bytes_per_line) { - // Data should match exactly. - memcpy(yuv_data->y, data, y_len); - } else { - HAL_LOGV("Changing padding on Y plane from %u to %u.", - bytes_per_line, - yuv_data->ystride); - // Wrong padding from V4L2. - copyWithPadding(reinterpret_cast(yuv_data->y), - reinterpret_cast(data), - yuv_data->ystride, - bytes_per_line, - height); - } - // C data. - // TODO(b/30119452): These calculations assume YCbCr_420_888. - size_t c_len = y_len / 4; - uint32_t c_bytes_per_line = bytes_per_line / 2; - // V4L2 is packed, meaning the data is stored as contiguous {y, cb, cr}. - uint8_t* cb_device = reinterpret_cast(data) + y_len; - uint8_t* cr_device = cb_device + c_len; - size_t step = yuv_data->chroma_step; - if (step == 1) { - // Still planar. - if (yuv_data->cstride == c_bytes_per_line) { - // Data should match exactly. - memcpy(yuv_data->cb, cb_device, c_len); - memcpy(yuv_data->cr, cr_device, c_len); - } else { - HAL_LOGV("Changing padding on C plane from %u to %u.", - c_bytes_per_line, - yuv_data->cstride); - // Wrong padding from V4L2. - copyWithPadding(reinterpret_cast(yuv_data->cb), - cb_device, - yuv_data->cstride, - c_bytes_per_line, - height / 2); - copyWithPadding(reinterpret_cast(yuv_data->cr), - cr_device, - yuv_data->cstride, - c_bytes_per_line, - height / 2); - } - } else { - // Desire semiplanar (cb and cr interleaved). - HAL_LOGV("Interleaving cb and cr. Padding going from %u to %u.", - c_bytes_per_line, - yuv_data->cstride); - uint32_t c_height = height / 2; - uint32_t c_width = camera_buffer->stream->width / 2; - // Zero out destination - uint8_t* cb_gralloc = reinterpret_cast(yuv_data->cb); - uint8_t* cr_gralloc = reinterpret_cast(yuv_data->cr); - memset(cb_gralloc, 0, c_width * c_height * step); - - // Interleaving means we need to copy the cb and cr bytes one by one. - for (size_t line = 0; line < c_height; ++line, - cb_gralloc += yuv_data->cstride, - cr_gralloc += yuv_data->cstride, - cb_device += c_bytes_per_line, - cr_device += c_bytes_per_line) { - for (size_t i = 0; i < c_width; ++i) { - *(cb_gralloc + (i * step)) = *(cb_device + i); - *(cr_gralloc + (i * step)) = *(cr_device + i); - } - } - } - } - - // Unlock. - int res = mModule->unlock(mModule, buffer); - if (res) { - HAL_LOGE("Failed to unlock buffer at %p", buffer); - return -ENODEV; - } - - return 0; -} - -int V4L2Gralloc::unlockAllBuffers() { - HAL_LOG_ENTER(); - - bool failed = false; - for (auto const& entry : mBufferMap) { - int res = mModule->unlock(mModule, *entry.second->camera_buffer->buffer); - if (res) { - failed = true; - } - // When there is a transform to be made, the buffer returned by lock() - // is dynamically allocated (to hold the pre-transform data). - if (entry.second->transform_dest) { - delete[] reinterpret_cast(entry.first); - } - // The BufferData entry is always dynamically allocated in lock(). - delete entry.second; - } - mBufferMap.clear(); - - // If any unlock failed, return error. - if (failed) { - return -ENODEV; - } - - return 0; -} - -} // namespace default_camera_hal diff --git a/modules/camera/3_4/v4l2_gralloc.h b/modules/camera/3_4/v4l2_gralloc.h deleted file mode 100644 index 82129e37..00000000 --- a/modules/camera/3_4/v4l2_gralloc.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 V4L2_CAMERA_HAL_V4L2_GRALLOC_H_ -#define V4L2_CAMERA_HAL_V4L2_GRALLOC_H_ - -#include - -#include - -#include -#include -#include - -namespace v4l2_camera_hal { - -// Generously allow up to 6MB (the largest JPEG on the RPi camera is about 5MB). -static constexpr size_t V4L2_MAX_JPEG_SIZE = 6000000; - -// V4L2Gralloc is a wrapper around relevant parts of a gralloc module, -// with some assistive transformations. -class V4L2Gralloc { - public: - // Use this method to create V4L2Gralloc objects. Functionally equivalent - // to "new V4L2Gralloc", except that it may return nullptr in case of failure. - static V4L2Gralloc* NewV4L2Gralloc(); - virtual ~V4L2Gralloc(); - - // Lock a camera buffer. Uses device buffer length, sets user pointer. - int lock(const camera3_stream_buffer_t* camera_buffer, - uint32_t bytes_per_line, - v4l2_buffer* device_buffer); - // Unlock a buffer that was locked by this helper (equality determined - // based on buffer user pointer, not the specific object). - int unlock(const v4l2_buffer* device_buffer); - // Release all held locks. - int unlockAllBuffers(); - - private: - // Constructor is private to allow failing on bad input. - // Use NewV4L2Gralloc instead. - V4L2Gralloc(const gralloc_module_t* module); - - const gralloc_module_t* mModule; - - struct BufferData { - const camera3_stream_buffer_t* camera_buffer; - // Below fields only used when a ycbcr format transform is necessary. - std::unique_ptr transform_dest; // nullptr if no transform. - uint32_t v4l2_bytes_per_line; - }; - // Map data pointer : BufferData about that buffer. - std::unordered_map mBufferMap; -}; - -} // namespace default_camera_hal - -#endif // V4L2_CAMERA_HAL_V4L2_GRALLOC_H_ diff --git a/modules/camera/3_4/v4l2_metadata_factory.cpp b/modules/camera/3_4/v4l2_metadata_factory.cpp index 3d9cfbb0..bc8806f7 100644 --- a/modules/camera/3_4/v4l2_metadata_factory.cpp +++ b/modules/camera/3_4/v4l2_metadata_factory.cpp @@ -27,7 +27,6 @@ #include "metadata/partial_metadata_factory.h" #include "metadata/property.h" #include "metadata/scaling_converter.h" -#include "v4l2_gralloc.h" namespace v4l2_camera_hal { @@ -37,6 +36,8 @@ const camera_metadata_rational_t kAeCompensationUnit = {1, 1000}; const int64_t kV4L2ExposureTimeStepNs = 100000; // According to spec, each unit of V4L2_CID_ISO_SENSITIVITY is ISO/1000. const int32_t kV4L2SensitivityDenominator = 1000; +// Generously allow up to 6MB (the largest size on the RPi Camera is about 5MB). +const size_t kV4L2MaxJpegSize = 6000000; int GetV4L2Metadata(std::shared_ptr device, std::unique_ptr* result) { @@ -433,10 +434,9 @@ int GetV4L2Metadata(std::shared_ptr device, ANDROID_JPEG_THUMBNAIL_SIZE, ANDROID_JPEG_AVAILABLE_THUMBNAIL_SIZES, {{{0, 0}}})); - // TODO(b/31022752): Get this from the device, - // not constant (from V4L2Gralloc.h). + // TODO(b/31022752): Get this from the device, not constant. components.insert(std::unique_ptr( - new Property(ANDROID_JPEG_MAX_SIZE, V4L2_MAX_JPEG_SIZE))); + new Property(ANDROID_JPEG_MAX_SIZE, kV4L2MaxJpegSize))); // TODO(b/31021672): Other JPEG controls (GPS, quality, orientation). // TODO(b/29939583): V4L2 can only support 1 stream at a time. // For now, just reporting minimum allowable for LIMITED devices. diff --git a/modules/camera/3_4/v4l2_wrapper.cpp b/modules/camera/3_4/v4l2_wrapper.cpp index 36d04116..d715e7ec 100644 --- a/modules/camera/3_4/v4l2_wrapper.cpp +++ b/modules/camera/3_4/v4l2_wrapper.cpp @@ -29,12 +29,15 @@ #include -#include "common.h" -#include "stream_format.h" -#include "v4l2_gralloc.h" +#include "arc/cached_frame.h" namespace v4l2_camera_hal { +using arc::AllocatedFrameBuffer; +using arc::SupportedFormat; +using arc::SupportedFormats; +using default_camera_hal::CaptureRequest; + const int32_t kStandardSizes[][2] = { {4096, 2160}, // 4KDCI (for USB camera) {3840, 2160}, // 4KUHD (for USB camera) @@ -50,20 +53,11 @@ const int32_t kStandardSizes[][2] = { }; V4L2Wrapper* V4L2Wrapper::NewV4L2Wrapper(const std::string device_path) { - std::unique_ptr gralloc(V4L2Gralloc::NewV4L2Gralloc()); - if (!gralloc) { - HAL_LOGE("Failed to initialize gralloc helper."); - return nullptr; - } - - return new V4L2Wrapper(device_path, std::move(gralloc)); + return new V4L2Wrapper(device_path); } -V4L2Wrapper::V4L2Wrapper(const std::string device_path, - std::unique_ptr gralloc) - : device_path_(std::move(device_path)), - gralloc_(std::move(gralloc)), - connection_count_(0) {} +V4L2Wrapper::V4L2Wrapper(const std::string device_path) + : device_path_(std::move(device_path)), connection_count_(0) {} V4L2Wrapper::~V4L2Wrapper() {} @@ -97,6 +91,10 @@ int V4L2Wrapper::Connect() { // (Alternatively, better hotplugging support may make this unecessary // by disabling cameras that get disconnected and checking newly connected // cameras, so Connect() is never called on an unsupported camera) + + supported_formats_ = GetSupportedFormats(); + qualified_formats_ = StreamFormat::GetQualifiedFormats(supported_formats_); + return 0; } @@ -114,15 +112,16 @@ void V4L2Wrapper::Disconnect() { --connection_count_; if (connection_count_ > 0) { HAL_LOGV("Disconnected from camera device %s. %d connections remain.", - device_path_.c_str()); + device_path_.c_str(), connection_count_); return; } device_fd_.reset(-1); // Includes close(). format_.reset(); - buffers_.clear(); - // Closing the device releases all queued buffers back to the user. - gralloc_->unlockAllBuffers(); + { + std::lock_guard buffer_lock(buffer_queue_lock_); + buffers_.clear(); + } } // Helper function. Should be used instead of ioctl throughout this class. @@ -146,7 +145,7 @@ int V4L2Wrapper::StreamOn() { int32_t type = format_->type(); if (IoctlLocked(VIDIOC_STREAMON, &type) < 0) { - HAL_LOGE("STREAMON fails: %s", strerror(errno)); + HAL_LOGE("STREAMON fails (%d): %s", errno, strerror(errno)); return -ENODEV; } @@ -164,20 +163,16 @@ int V4L2Wrapper::StreamOff() { int32_t type = format_->type(); int res = IoctlLocked(VIDIOC_STREAMOFF, &type); // Calling STREAMOFF releases all queued buffers back to the user. - int gralloc_res = gralloc_->unlockAllBuffers(); // No buffers in flight. - for (size_t i = 0; i < buffers_.size(); ++i) { - buffers_[i] = false; - } if (res < 0) { HAL_LOGE("STREAMOFF fails: %s", strerror(errno)); return -ENODEV; } - if (gralloc_res < 0) { - HAL_LOGE("Failed to unlock all buffers after turning stream off."); - return gralloc_res; + std::lock_guard lock(buffer_queue_lock_); + for (auto& buffer : buffers_) { + buffer.active = false; + buffer.request.reset(); } - HAL_LOGV("Stream turned off."); return 0; } @@ -316,6 +311,36 @@ int V4L2Wrapper::SetControl(uint32_t control_id, return 0; } +const SupportedFormats V4L2Wrapper::GetSupportedFormats() { + SupportedFormats formats; + std::set pixel_formats; + int res = GetFormats(&pixel_formats); + if (res) { + HAL_LOGE("Failed to get device formats."); + return formats; + } + + arc::SupportedFormat supported_format; + std::set> frame_sizes; + + for (auto pixel_format : pixel_formats) { + supported_format.fourcc = pixel_format; + + frame_sizes.clear(); + res = GetFormatFrameSizes(pixel_format, &frame_sizes); + if (res) { + HAL_LOGE("Failed to get frame sizes for format: 0x%x", pixel_format); + continue; + } + for (auto frame_size : frame_sizes) { + supported_format.width = frame_size[0]; + supported_format.height = frame_size[1]; + formats.push_back(supported_format); + } + } + return formats; +} + int V4L2Wrapper::GetFormats(std::set* v4l2_formats) { HAL_LOG_ENTER(); @@ -336,6 +361,22 @@ int V4L2Wrapper::GetFormats(std::set* v4l2_formats) { return 0; } +int V4L2Wrapper::GetQualifiedFormats(std::vector* v4l2_formats) { + HAL_LOG_ENTER(); + if (!connected()) { + HAL_LOGE( + "Device is not connected, qualified formats may not have been set."); + return -EINVAL; + } + v4l2_formats->clear(); + std::set unique_fourccs; + for (auto& format : qualified_formats_) { + unique_fourccs.insert(format.fourcc); + } + v4l2_formats->assign(unique_fourccs.begin(), unique_fourccs.end()); + return 0; +} + int V4L2Wrapper::GetFormatFrameSizes(uint32_t v4l2_format, std::set>* sizes) { v4l2_frmsizeenum size_query; @@ -459,8 +500,6 @@ int V4L2Wrapper::SetFormat(const StreamFormat& desired_format, return 0; } - // Not in the correct format, set the new one. - if (format_) { // If we had an old format, first request 0 buffers to inform the device // we're no longer using any previously "allocated" buffers from the old @@ -473,19 +512,34 @@ int V4L2Wrapper::SetFormat(const StreamFormat& desired_format, } } + // Select the matching format, or if not available, select a qualified format + // we can convert from. + SupportedFormat format; + if (!StreamFormat::FindBestFitFormat(supported_formats_, qualified_formats_, + desired_format.v4l2_pixel_format(), + desired_format.width(), + desired_format.height(), &format)) { + HAL_LOGE( + "Unable to find supported resolution in list, " + "width: %d, height: %d", + desired_format.width(), desired_format.height()); + return -EINVAL; + } + // Set the camera to the new format. v4l2_format new_format; - desired_format.FillFormatRequest(&new_format); + const StreamFormat resolved_format(format); + resolved_format.FillFormatRequest(&new_format); + // TODO(b/29334616): When async, this will need to check if the stream // is on, and if so, lock it off while setting format. - if (IoctlLocked(VIDIOC_S_FMT, &new_format) < 0) { HAL_LOGE("S_FMT failed: %s", strerror(errno)); return -ENODEV; } // Check that the driver actually set to the requested values. - if (desired_format != new_format) { + if (resolved_format != new_format) { HAL_LOGE("Device doesn't support desired stream configuration."); return -EINVAL; } @@ -512,28 +566,22 @@ int V4L2Wrapper::RequestBuffers(uint32_t num_requested) { int res = IoctlLocked(VIDIOC_REQBUFS, &req_buffers); // Calling REQBUFS releases all queued buffers back to the user. - int gralloc_res = gralloc_->unlockAllBuffers(); if (res < 0) { HAL_LOGE("REQBUFS failed: %s", strerror(errno)); return -ENODEV; } - if (gralloc_res < 0) { - HAL_LOGE("Failed to unlock all buffers when setting up new buffers."); - return gralloc_res; - } // V4L2 will set req_buffers.count to a number of buffers it can handle. if (num_requested > 0 && req_buffers.count < 1) { HAL_LOGE("REQBUFS claims it can't handle any buffers."); return -ENODEV; } - buffers_.resize(req_buffers.count, false); - + buffers_.resize(req_buffers.count); return 0; } -int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, - uint32_t* enqueued_index) { +int V4L2Wrapper::EnqueueRequest( + std::shared_ptr request) { if (!format_) { HAL_LOGE("Stream format must be set before enqueuing buffers."); return -ENODEV; @@ -545,9 +593,8 @@ int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, int index = -1; { std::lock_guard guard(buffer_queue_lock_); - for (int i = 0; i < buffers_.size(); ++i) { - if (!buffers_[i]) { - buffers_[i] = true; + for (size_t i = 0; i < buffers_.size(); ++i) { + if (!buffers_[i].active) { index = i; break; } @@ -572,36 +619,40 @@ int V4L2Wrapper::EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, HAL_LOGE("QUERYBUF fails: %s", strerror(errno)); // Return buffer index. std::lock_guard guard(buffer_queue_lock_); - buffers_[index] = false; + buffers_[index].active = false; return -ENODEV; } - // Lock the buffer for writing (fills in the user pointer field). - int res = - gralloc_->lock(camera_buffer, format_->bytes_per_line(), &device_buffer); - if (res) { - HAL_LOGE("Gralloc failed to lock buffer."); - // Return buffer index. + // Setup our request context and fill in the user pointer field. + RequestContext* request_context; + void* data; + { std::lock_guard guard(buffer_queue_lock_); - buffers_[index] = false; - return res; + request_context = &buffers_[index]; + request_context->camera_buffer->SetDataSize(device_buffer.length); + request_context->camera_buffer->Reset(); + request_context->camera_buffer->SetFourcc(format_->v4l2_pixel_format()); + request_context->camera_buffer->SetWidth(format_->width()); + request_context->camera_buffer->SetHeight(format_->height()); + request_context->request = request; + data = request_context->camera_buffer->GetData(); } + device_buffer.m.userptr = reinterpret_cast(data); + + // Pass the buffer to the camera. if (IoctlLocked(VIDIOC_QBUF, &device_buffer) < 0) { HAL_LOGE("QBUF fails: %s", strerror(errno)); - gralloc_->unlock(&device_buffer); - // Return buffer index. - std::lock_guard guard(buffer_queue_lock_); - buffers_[index] = false; return -ENODEV; } - if (enqueued_index) { - *enqueued_index = index; - } + // Mark the buffer as in flight. + std::lock_guard guard(buffer_queue_lock_); + request_context->active = true; + return 0; } -int V4L2Wrapper::DequeueBuffer(uint32_t* dequeued_index) { +int V4L2Wrapper::DequeueRequest(std::shared_ptr* request) { if (!format_) { HAL_LOGV( "Format not set, so stream can't be on, " @@ -625,23 +676,63 @@ int V4L2Wrapper::DequeueBuffer(uint32_t* dequeued_index) { } } - // Mark the buffer as no longer in flight. - { - std::lock_guard guard(buffer_queue_lock_); - buffers_[buffer.index] = false; + std::lock_guard guard(buffer_queue_lock_); + RequestContext* request_context = &buffers_[buffer.index]; + + // Lock the camera stream buffer for painting. + const camera3_stream_buffer_t* stream_buffer = + &request_context->request->output_buffers[0]; + uint32_t fourcc = + StreamFormat::HalToV4L2PixelFormat(stream_buffer->stream->format); + + if (request) { + *request = request_context->request; } - // Now that we're done painting the buffer, we can unlock it. - res = gralloc_->unlock(&buffer); + // Note that the device buffer length is passed to the output frame. If the + // GrallocFrameBuffer does not have support for the transformation to + // |fourcc|, it will assume that the amount of data to lock is based on + // |buffer.length|, otherwise it will use the ImageProcessor::ConvertedSize. + arc::GrallocFrameBuffer output_frame( + *stream_buffer->buffer, stream_buffer->stream->width, + stream_buffer->stream->height, fourcc, buffer.length, + stream_buffer->stream->usage); + res = output_frame.Map(); if (res) { - HAL_LOGE("Gralloc failed to unlock buffer after dequeueing."); - return res; + HAL_LOGE("Failed to map output frame."); + request_context->request.reset(); + return -EINVAL; + } + if (request_context->camera_buffer->GetFourcc() == fourcc && + request_context->camera_buffer->GetWidth() == + stream_buffer->stream->width && + request_context->camera_buffer->GetHeight() == + stream_buffer->stream->height) { + // If no format conversion needs to be applied, directly copy the data over. + memcpy(output_frame.GetData(), request_context->camera_buffer->GetData(), + request_context->camera_buffer->GetDataSize()); + } else { + // Perform the format conversion. + arc::CachedFrame cached_frame; + cached_frame.SetSource(request_context->camera_buffer.get(), 0); + cached_frame.Convert(request_context->request->settings, &output_frame); } - if (dequeued_index) { - *dequeued_index = buffer.index; - } + request_context->request.reset(); + // Mark the buffer as not in flight. + request_context->active = false; return 0; } +int V4L2Wrapper::GetInFlightBufferCount() { + int count = 0; + std::lock_guard guard(buffer_queue_lock_); + for (auto& buffer : buffers_) { + if (buffer.active) { + count++; + } + } + return count; +} + } // namespace v4l2_camera_hal diff --git a/modules/camera/3_4/v4l2_wrapper.h b/modules/camera/3_4/v4l2_wrapper.h index c3ad2727..4a8d5170 100644 --- a/modules/camera/3_4/v4l2_wrapper.h +++ b/modules/camera/3_4/v4l2_wrapper.h @@ -26,11 +26,14 @@ #include +#include "arc/common_types.h" +#include "arc/frame_buffer.h" +#include "capture_request.h" #include "common.h" #include "stream_format.h" -#include "v4l2_gralloc.h" namespace v4l2_camera_hal { + class V4L2Wrapper { public: // Use this method to create V4L2Wrapper objects. Functionally equivalent @@ -67,8 +70,10 @@ class V4L2Wrapper { int32_t* result = nullptr); // Manage format. virtual int GetFormats(std::set* v4l2_formats); + virtual int GetQualifiedFormats(std::vector* v4l2_formats); virtual int GetFormatFrameSizes(uint32_t v4l2_format, std::set>* sizes); + // Durations are returned in ns. virtual int GetFormatFrameDurationRange( uint32_t v4l2_format, @@ -77,15 +82,16 @@ class V4L2Wrapper { virtual int SetFormat(const StreamFormat& desired_format, uint32_t* result_max_buffers); // Manage buffers. - virtual int EnqueueBuffer(const camera3_stream_buffer_t* camera_buffer, - uint32_t* enqueued_index = nullptr); - virtual int DequeueBuffer(uint32_t* dequeued_index = nullptr); + virtual int EnqueueRequest( + std::shared_ptr request); + virtual int DequeueRequest( + std::shared_ptr* request); + virtual int GetInFlightBufferCount(); private: // Constructor is private to allow failing on bad input. // Use NewV4L2Wrapper instead. - V4L2Wrapper(const std::string device_path, - std::unique_ptr gralloc); + V4L2Wrapper(const std::string device_path); // Connect or disconnect to the device. Access by creating/destroying // a V4L2Wrapper::Connection object. @@ -99,20 +105,19 @@ class V4L2Wrapper { inline bool connected() { return device_fd_.get() >= 0; } + // Format management. + const arc::SupportedFormats GetSupportedFormats(); + // The camera device path. For example, /dev/video0. const std::string device_path_; // The opened device fd. android::base::unique_fd device_fd_; // The underlying gralloc module. - std::unique_ptr gralloc_; + // std::unique_ptr gralloc_; // Whether or not the device supports the extended control query. bool extended_query_supported_; // The format this device is set up for. std::unique_ptr format_; - // Map indecies to buffer status. True if the index is in-flight. - // |buffers_.size()| will always be the maximum number of buffers this device - // can handle in its current format. - std::vector buffers_; // Lock protecting use of the buffer tracker. std::mutex buffer_queue_lock_; // Lock protecting use of the device. @@ -121,6 +126,28 @@ class V4L2Wrapper { std::mutex connection_lock_; // Reference count connections. int connection_count_; + // Supported formats. + arc::SupportedFormats supported_formats_; + // Qualified formats. + arc::SupportedFormats qualified_formats_; + + class RequestContext { + public: + RequestContext() + : active(false), + camera_buffer(std::make_shared(0)){}; + ~RequestContext(){}; + // Indicates whether this request context is in use. + bool active; + // Buffer handles of the context. + std::shared_ptr camera_buffer; + std::shared_ptr request; + }; + + // Map of in flight requests. + // |buffers_.size()| will always be the maximum number of buffers this device + // can handle in its current format. + std::vector buffers_; friend class Connection; friend class V4L2WrapperMock; diff --git a/modules/camera/3_4/v4l2_wrapper_mock.h b/modules/camera/3_4/v4l2_wrapper_mock.h index d423cc59..f98bc948 100644 --- a/modules/camera/3_4/v4l2_wrapper_mock.h +++ b/modules/camera/3_4/v4l2_wrapper_mock.h @@ -27,7 +27,7 @@ namespace v4l2_camera_hal { class V4L2WrapperMock : public V4L2Wrapper { public: - V4L2WrapperMock() : V4L2Wrapper("", nullptr){}; + V4L2WrapperMock() : V4L2Wrapper(""){}; MOCK_METHOD0(StreamOn, int()); MOCK_METHOD0(StreamOff, int()); MOCK_METHOD2(QueryControl, @@ -36,17 +36,15 @@ class V4L2WrapperMock : public V4L2Wrapper { MOCK_METHOD3(SetControl, int(uint32_t control_id, int32_t desired, int32_t* result)); MOCK_METHOD1(GetFormats, int(std::set*)); + MOCK_METHOD1(GetQualifiedFormats, int(std::vector*)); MOCK_METHOD2(GetFormatFrameSizes, int(uint32_t, std::set>*)); MOCK_METHOD3(GetFormatFrameDurationRange, int(uint32_t, const std::array&, std::array*)); - MOCK_METHOD4(SetFormat, - int(int format, - uint32_t width, - uint32_t height, - uint32_t* result_max_buffers)); + MOCK_METHOD2(SetFormat, int(const StreamFormat& desired_format, + uint32_t* result_max_buffers)); MOCK_METHOD2(EnqueueBuffer, int(const camera3_stream_buffer_t* camera_buffer, uint32_t* enqueued_index)); From 2b55708fbb6b2a1d04a5c540121be55ca02b1be9 Mon Sep 17 00:00:00 2001 From: Shawn Willden Date: Tue, 9 Jan 2018 06:55:15 -0700 Subject: [PATCH 17/50] Add KM_ALGORITHM_TRIPLE_DES to keymaster_defs.h Test: system/keymaster unit tests Change-Id: I1ed56e543b657155c9194bc30616747d51aef7df --- include/hardware/keymaster_defs.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 7d1b348d..e58d56a3 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -182,6 +182,7 @@ typedef enum { /* Block ciphers algorithms */ KM_ALGORITHM_AES = 32, + KM_ALGORITHM_TRIPLE_DES = 33, /* MAC algorithms */ KM_ALGORITHM_HMAC = 128, From 343f309e0ab77ed44bfe7ca36cb88ecb29245def Mon Sep 17 00:00:00 2001 From: Frank Salim Date: Thu, 5 Oct 2017 21:58:47 -0700 Subject: [PATCH 18/50] Add KM_PURPOSE_WRAP to keymaster_defs for wrapped key import AndroidKeymaster depends on keymaster_defs and needs the new purpose for secure key import. Test: system/keymaster/tests/android_keymaster_tests Change-Id: I8ab6d9756689342bc5865861c89c5ccc87179454 --- include/hardware/keymaster_defs.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 7d1b348d..1f6ec558 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -296,6 +296,8 @@ typedef enum { KM_PURPOSE_SIGN = 2, /* Usable with RSA, EC and HMAC keys. */ KM_PURPOSE_VERIFY = 3, /* Usable with RSA, EC and HMAC keys. */ KM_PURPOSE_DERIVE_KEY = 4, /* Usable with EC keys. */ + KM_PURPOSE_WRAP = 5, /* Usable with wrapped keys. */ + } keymaster_purpose_t; typedef struct { From 1a9044ededa971daeec65f27cffa1667d5e938af Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Tue, 16 Jan 2018 14:00:23 -0800 Subject: [PATCH 19/50] Removes deprecated audio property in vehicle hal Bug: 72054677 Test: lunch gcar_emu-x86 && m -j Change-Id: Ia70bf17e0343704c5ca3468ad86145e7078696f7 --- include/hardware/vehicle.h | 440 ------------------------------------- 1 file changed, 440 deletions(-) diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h index 8b28e7a0..aa92815e 100644 --- a/include/hardware/vehicle.h +++ b/include/hardware/vehicle.h @@ -542,446 +542,6 @@ enum vehicle_radio_consts { VEHICLE_RADIO_PRESET_MIN_VALUE = 1, }; -/** - * Represents audio focus state of Android side. Note that car's audio module will own audio - * focus and grant audio focus to Android side when requested by Android side. The focus has both - * per stream characteristics and global characteristics. - * - * Focus request (get of this property) will take the following form in int32_vec4: - * int32_array[0]: vehicle_audio_focus_request type - * int32_array[1]: bit flags of streams requested by this focus request. There can be up to - * 32 streams. - * int32_array[2]: External focus state flags. For request, only flag like - * VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG or - * VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG can be used. - * VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG is for case like radio where android - * side app still needs to hold focus but playback is done outside Android. - * VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG is for muting media channel - * including radio. VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG can be set even - * if android side releases focus (request type REQUEST_RELEASE). In that case, - * audio module should maintain mute state until user's explicit action to - * play some media. - * int32_array[3]: Currently active audio contexts. Use combination of flags from - * vehicle_audio_context_flag. - * This can be used as a hint to adjust audio policy or other policy decision. - * Note that there can be multiple context active at the same time. And android - * can send the same focus request type gain due to change in audio contexts. - * Note that each focus request can request multiple streams that is expected to be used for - * the current request. But focus request itself is global behavior as GAIN or GAIN_TRANSIENT - * expects all sounds played by car's audio module to stop. Note that stream already allocated to - * android before this focus request should not be affected by focus request. - * - * Focus response (set and subscription callback for this property) will take the following form: - * int32_array[0]: vehicle_audio_focus_state type - * int32_array[1]: bit flags of streams allowed. - * int32_array[2]: External focus state: bit flags of currently active audio focus in car - * side (outside Android). Active audio focus does not necessarily mean currently - * playing, but represents the state of having focus or waiting for focus - * (pause state). - * One or combination of flags from vehicle_audio_ext_focus_flag. - * 0 means no active audio focus holder outside Android. - * The state will have following values for each vehicle_audio_focus_state_type: - * GAIN: 0 or VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY when radio is active in - * Android side. - * GAIN_TRANSIENT: 0. Can be VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT or - * VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT if android side has requested - * GAIN_TRANSIENT_MAY_DUCK and car side is ducking. - * LOSS: 0 when no focus is audio is active in car side. - * VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT when car side is playing something - * permanent. - * LOSS_TRANSIENT: always should be VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT - * int32_array[3]: context requested by android side when responding to focus request. - * When car side is taking focus away, this should be zero. - * - * A focus response should be sent per each focus request even if there is no change in - * focus state. This can happen in case like focus request only involving context change - * where android side still needs matching focus response to confirm that audio module - * has made necessary changes. - * - * If car does not support VEHICLE_PROPERTY_AUDIO_FOCUS, focus is assumed to be granted always. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC4 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_AUDIO_FOCUS (0x00000900) - -enum vehicle_audio_focus_request { - VEHICLE_AUDIO_FOCUS_REQUEST_GAIN = 0x1, - VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT = 0x2, - VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_MAY_DUCK = 0x3, - /** - * This is for the case where android side plays sound like UI feedback - * and car side does not need to duck existing playback as long as - * requested stream is available. - */ - VEHICLE_AUDIO_FOCUS_REQUEST_GAIN_TRANSIENT_NO_DUCK = 0x4, - VEHICLE_AUDIO_FOCUS_REQUEST_RELEASE = 0x5, -}; - -enum vehicle_audio_focus_state { - /** - * Android side has permanent focus and can play allowed streams. - */ - VEHICLE_AUDIO_FOCUS_STATE_GAIN = 0x1, - /** - * Android side has transient focus and can play allowed streams. - */ - VEHICLE_AUDIO_FOCUS_STATE_GAIN_TRANSIENT = 0x2, - /** - * Car audio module is playing guidance kind of sound outside Android. Android side can - * still play through allowed streams with ducking. - */ - VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_CAN_DUCK = 0x3, - /** - * Car audio module is playing transient sound outside Android. Android side should stop - * playing any sounds. - */ - VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT = 0x4, - /** - * Android side has lost focus and cannot play any sound. - */ - VEHICLE_AUDIO_FOCUS_STATE_LOSS = 0x5, - /** - * car audio module is playing safety critical sound, and Android side cannot request focus - * until the current state is finished. car audio module should restore it to the previous - * state when it can allow Android to play. - */ - VEHICLE_AUDIO_FOCUS_STATE_LOSS_TRANSIENT_EXLCUSIVE = 0x6, -}; - -/** - * Flags to represent multiple streams by combining these. - */ -enum vehicle_audio_stream_flag { - VEHICLE_AUDIO_STREAM_STREAM0_FLAG = (0x1<<0), - VEHICLE_AUDIO_STREAM_STREAM1_FLAG = (0x1<<1), - VEHICLE_AUDIO_STREAM_STREAM2_FLAG = (0x1<<2), -}; - -/** - * Represents stream number (always 0 to N -1 where N is max number of streams). - * Can be used for audio related property expecting one stream. - */ -enum vehicle_audio_stream { - VEHICLE_AUDIO_STREAM0 = 0, - VEHICLE_AUDIO_STREAM1 = 1, -}; - -/** - * Flag to represent external focus state (outside Android). - */ -enum vehicle_audio_ext_focus_flag { - /** - * No external focus holder. - */ - VEHICLE_AUDIO_EXT_FOCUS_NONE_FLAG = 0x0, - /** - * Car side (outside Android) has component holding GAIN kind of focus state. - */ - VEHICLE_AUDIO_EXT_FOCUS_CAR_PERMANENT_FLAG = 0x1, - /** - * Car side (outside Android) has component holding GAIN_TRANSIENT kind of focus state. - */ - VEHICLE_AUDIO_EXT_FOCUS_CAR_TRANSIENT_FLAG = 0x2, - /** - * Car side is expected to play something while focus is held by Android side. One example - * can be radio attached in car side. But Android's radio app still should have focus, - * and Android side should be in GAIN state, but media stream will not be allocated to Android - * side and car side can play radio any time while this flag is active. - */ - VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG = 0x4, - /** - * Car side should mute any media including radio. This can be used with any focus request - * including GAIN* and RELEASE. - */ - VEHICLE_AUDIO_EXT_FOCUS_CAR_MUTE_MEDIA_FLAG = 0x8, -}; - -/** - * Index in int32_array for VEHICLE_PROPERTY_AUDIO_FOCUS property. - */ -enum vehicle_audio_focus_index { - VEHICLE_AUDIO_FOCUS_INDEX_FOCUS = 0, - VEHICLE_AUDIO_FOCUS_INDEX_STREAMS = 1, - VEHICLE_AUDIO_FOCUS_INDEX_EXTERNAL_FOCUS_STATE = 2, - VEHICLE_AUDIO_FOCUS_INDEX_AUDIO_CONTEXTS = 3, -}; - -/** - * Flags to tell the current audio context. - */ -enum vehicle_audio_context_flag { - /** Music playback is currently active. */ - VEHICLE_AUDIO_CONTEXT_MUSIC_FLAG = 0x1, - /** Navigation is currently running. */ - VEHICLE_AUDIO_CONTEXT_NAVIGATION_FLAG = 0x2, - /** Voice command session is currently running. */ - VEHICLE_AUDIO_CONTEXT_VOICE_COMMAND_FLAG = 0x4, - /** Voice call is currently active. */ - VEHICLE_AUDIO_CONTEXT_CALL_FLAG = 0x8, - /** Alarm is active. This may be only used in VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY. */ - VEHICLE_AUDIO_CONTEXT_ALARM_FLAG = 0x10, - /** - * Notification sound is active. This may be only used in VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY. - */ - VEHICLE_AUDIO_CONTEXT_NOTIFICATION_FLAG = 0x20, - /** - * Context unknown. Only used for VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY to represent default - * stream for unknown contents. - */ - VEHICLE_AUDIO_CONTEXT_UNKNOWN_FLAG = 0x40, - /** Safety alert / warning is played. */ - VEHICLE_AUDIO_CONTEXT_SAFETY_ALERT_FLAG = 0x80, - /** CD / DVD kind of audio is played */ - VEHICLE_AUDIO_CONTEXT_CD_ROM_FLAG = 0x100, - /** Aux audio input is played */ - VEHICLE_AUDIO_CONTEXT_AUX_AUDIO_FLAG = 0x200, - /** system sound like UI feedback */ - VEHICLE_AUDIO_CONTEXT_SYSTEM_SOUND_FLAG = 0x400, - /** Radio is played */ - VEHICLE_AUDIO_CONTEXT_RADIO_FLAG = 0x800, - /** Ext source is played. This is for tagging generic ext sources. */ - VEHICLE_AUDIO_CONTEXT_EXT_SOURCE_FLAG = 0x1000, -}; - -/** - * Property to control audio volume of each audio context. - * - * vehicle_prop_config_t - * config_array[0] : bit flags of all supported audio contexts. If this is 0, - * audio volume is controlled per physical stream - * config_array[1] : flags defined in vehicle_audio_volume_capability_flag to - * represent audio module's capability. - * - * Data type looks like: - * int32_array[0] : stream context as defined in vehicle_audio_context_flag. If only physical - stream is supported (config_array[0] == 0), this will represent physical - stream number. - * int32_array[1] : volume level, valid range is 0 to int32_max_value defined in config. - * 0 will be mute state. int32_min_value in config should be always 0. - * int32_array[2] : One of vehicle_audio_volume_state. - * - * This property requires per stream based get. HAL implementation should check stream number - * in get call to return the right volume. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC3 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_flags all audio contexts supported. - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_AUDIO_VOLUME (0x00000901) - - -/** - * flags to represent capability of audio volume property. - * used in config_array[1] of vehicle_prop_config_t. - */ -enum vehicle_audio_volume_capability_flag { - /** - * External audio module or vehicle hal has persistent storage - * to keep the volume level. This should be set only when per context - * volume level is supproted. When this is set, audio volume level per - * each context will be retrieved from the property when systen starts up. - * And external audio module is also expected to adjust volume automatically - * whenever there is an audio context change. - * When this flag is not set, android side will assume that there is no - * persistent storage and stored value in android side will be used to - * initialize the volume level. And android side will set volume level - * of each physical streams whenever there is an audio context change. - */ - VEHICLE_AUDIO_VOLUME_CAPABILITY_PERSISTENT_STORAGE = 0x1, - /** - * When this flag is set, the H/W can support only single master volume for all streams. - * There is no way to set volume level differently per each stream or context. - */ - VEHICLE_AUDIO_VOLUME_CAPABILITY_MASTER_VOLUME_ONLY = 0x2, -}; - - -/** - * enum to represent audio volume state. - */ -enum vehicle_audio_volume_state { - VEHICLE_AUDIO_VOLUME_STATE_OK = 0, - /** - * Audio volume has reached volume limit set in VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT - * and user's request to increase volume further is not allowed. - */ - VEHICLE_AUDIO_VOLUME_STATE_LIMIT_REACHED = 1, -}; - -/** - * Index in int32_array for VEHICLE_PROPERTY_AUDIO_VOLUME property. - */ -enum vehicle_audio_volume_index { - VEHICLE_AUDIO_VOLUME_INDEX_STREAM = 0, - VEHICLE_AUDIO_VOLUME_INDEX_VOLUME = 1, - VEHICLE_AUDIO_VOLUME_INDEX_STATE = 2, -}; - -/** - * Property for handling volume limit set by user. This limits maximum volume that can be set - * per each context or physical stream. - * - * vehicle_prop_config_t - * config_array[0] : bit flags of all supported audio contexts. If this is 0, - * audio volume is controlled per physical stream - * config_array[1] : flags defined in vehicle_audio_volume_capability_flag to - * represent audio module's capability. - * - * Data type looks like: - * int32_array[0] : stream context as defined in vehicle_audio_context_flag. If only physical - * stream is supported (config_array[0] == 0), this will represent physical - * stream number. - * int32_array[1] : maximum volume set to the stream. If there is no restriction, this value - * will be bigger than VEHICLE_PROPERTY_AUDIO_VOLUME's max value. - * - * If car does not support this feature, this property should not be populated by HAL. - * This property requires per stream based get. HAL implementation should check stream number - * in get call to return the right volume. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC2 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_flags all audio contexts supported. - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT (0x00000902) - -/** - * Index in int32_array for VEHICLE_PROPERTY_AUDIO_VOLUME_LIMIT property. - */ -enum vehicle_audio_volume_limit_index { - VEHICLE_AUDIO_VOLUME_LIMIT_INDEX_STREAM = 0, - VEHICLE_AUDIO_VOLUME_LIMIT_INDEX_MAX_VOLUME = 1, -}; - -/** - * Property to share audio routing policy of android side. This property is set at the beginning - * to pass audio policy in android side down to vehicle HAL and car audio module. - * This can be used as a hint to adjust audio policy or other policy decision. - * - * int32_array[0] : audio stream where the audio for the application context will be routed - * by default. Note that this is the default setting from system, but each app - * may still use different audio stream for whatever reason. - * int32_array[1] : All audio contexts that will be sent through the physical stream. Flag - * is defined in vehicle_audio_context_flag. - - * Setting of this property will be done for all available physical streams based on audio H/W - * variant information acquired from VEHICLE_PROPERTY_AUDIO_HW_VARIANT property. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC2 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_WRITE - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY (0x00000903) - -/** - * Index in int32_array for VEHICLE_PROPERTY_AUDIO_ROUTING_POLICY property. - */ -enum vehicle_audio_routing_policy_index { - VEHICLE_AUDIO_ROUTING_POLICY_INDEX_STREAM = 0, - VEHICLE_AUDIO_ROUTING_POLICY_INDEX_CONTEXTS = 1, -}; - -/** -* Property to return audio H/W variant type used in this car. This allows android side to -* support different audio policy based on H/W variant used. Note that other components like -* CarService may need overlay update to support additional variants. If this property does not -* exist, default audio policy will be used. -* -* @value_type VEHICLE_VALUE_TYPE_INT32 -* @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC -* @access VEHICLE_PROP_ACCESS_READ -* @config_flags Additional info on audio H/W. Should use vehicle_audio_hw_variant_config_flag for -* this. -* @data_member int32_value -*/ -#define VEHICLE_PROPERTY_AUDIO_HW_VARIANT (0x00000904) - -/** - * Flag to be used in vehicle_prop_config.config_flags for VEHICLE_PROPERTY_AUDIO_HW_VARIANT. - */ -enum vehicle_audio_hw_variant_config_flag { - /** - * Flag to tell that radio is internal to android and radio should - * be treated like other android stream like media. - * When this flag is not set or AUDIO_HW_VARIANT does not exist, - * radio is treated as external module. This brins some delta in audio focus - * handling as well. - */ - VEHICLE_AUDIO_HW_VARIANT_FLAG_INTERNAL_RADIO_FLAG = 0x1, -}; - -/** audio routing for AM/FM. This should be also be the value when there is only one - radio module in the system. */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_AM_FM "RADIO_AM_FM" -/** Should be added only when there is a separate radio module with HD capability. */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_AM_FM_HD "RADIO_AM_FM_HD" -/** For digial audio broadcasting type of radio */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_DAB "RADIO_DAB" -/** For satellite type of radio */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_RADIO_SATELLITE "RADIO_SATELLITE" -/** For CD or DVD */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_CD_DVD "CD_DVD" -/** For 1st auxiliary input */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_AUX_IN0 "AUX_IN0" -/** For 2nd auxiliary input */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_AUX_IN1 "AUX_IN1" -/** For navigation guidance from outside android */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_NAV_GUIDANCE "EXT_NAV_GUIDANCE" -/** For voice command from outside android */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_VOICE_COMMAND "EXT_VOICE_COMMAND" -/** For voice call from outside android */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_VOICE_CALL "EXT_VOICE_CALL" -/** For safety alert from outside android */ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_EXT_SAFETY_ALERT "EXT_SAFETY_ALERT" - -/** -* Property to pass hint on external audio routing. When android side request focus -* with VEHICLE_AUDIO_EXT_FOCUS_CAR_PLAY_ONLY_FLAG flag, this property will be set -* before setting AUDIO_FOCUS property as a hint for external audio source routing. -* Note that setting this property alone should not trigger any change. -* Audio routing should be changed only when AUDIO_FOCUS property is set. Note that -* this property allows passing custom value as long as it is defined in config_string. -* This allows supporting non-standard routing options through this property. -* It is recommended to use separate name space for custom property to prevent conflict in future -* android releases. -* Enabling each external routing option is done by enabling each bit flag for the routing. -* This property can support up to 128 external routings. -* To give full flexibility, there is no standard definition for each bit flag and -* assigning each big flag to specific routing type is decided by config_string. -* config_string has format of each entry separated by ',' -* and each entry has format of bitFlagPositon:typeString[:physicalStreamNumber]. -* bitFlagPosition: represents which big flag will be set to enable this routing. 0 means -* LSB in int32_array[0]. 31 will be MSB in int32_array[0]. 127 will MSB in int32_array[3]. -* typeString: string representation of external routing. Some types are already defined -* in VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_SOURCE_* and use them first before adding something -* custom. Applications will find each routing using this string. -* physicalStreamNumber: This part is optional and represents physical stream to android -* which will be disabled when this routing is enabled. If not specified, this routing -* should not affect physical streams to android. -* As an example, let's assume a system with two physical streams, 0 for media and 1 for -* nav guidance. And let's assume external routing option of am fm radio, external navigation -* guidance, satellite radio, and one custom. Let's assume that radio and satellite replaces -* physical stream 0 and external navigation replaces physical stream 1. And bit flag will be -* assigned in the order listed above. This configuration will look like this in config_string: -* "0:RADIO_AM_FM:0,1:EXT_NAV_GUIDANCE:1,2:RADIO_SATELLITE:0,3:com.test.SOMETHING_CUSTOM" -* When android requests RADIO_AM_FM, int32_array[0] will be set to 0x1. -* When android requests RADIO_SATELLITE + EXT_NAV_GUIDANCE, int32_array[0] will be set to 0x2|0x4. -* -* @value_type VEHICLE_VALUE_TYPE_INT32_VEC4 -* @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE -* @access VEHICLE_PROP_ACCESS_WRITE|VEHICLE_PROP_ACCESS_READ_WRITE -* @config_string List of all avaiable external source in the system. -* @data_member int32_array -*/ -#define VEHICLE_PROPERTY_AUDIO_EXT_ROUTING_HINT (0x00000905) - /** * Property to control power state of application processor. * From bf39eb54de37773a7b51583a4886edd465b1fc45 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Wed, 29 Nov 2017 15:16:03 -0800 Subject: [PATCH 20/50] camera3: Add logical camera support in HAL 3.5 - Add ability to specify the camera id to which a particular camera3_stream belongs. - Update documentation about the camera characteristics of logical camera. Test: Camera2.apk and GoogleCamera.apk Bug: 64691172 Change-Id: Ie2e235e8bc8124596785db8dad25549bec4232aa --- include/hardware/camera3.h | 38 +++++++++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index 11e24910..d140ae05 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2013 The Android Open Source Project + * Copyright (C) 2013-2018 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. @@ -158,7 +158,7 @@ * - ANDROID_SENSOR_OPAQUE_RAW_SIZE * - ANDROID_SENSOR_OPTICAL_BLACK_REGIONS * - * 3.5: Minor additions to supported metadata and changes to camera3_stream_configuration. + * 3.5: Minor revisions to support session parameters and logical multi camera: * * - Add ANDROID_REQUEST_AVAILABLE_SESSION_KEYS static metadata, which is * optional for implementations that want to support session parameters. If support is @@ -169,6 +169,15 @@ * * - Add a session parameter field to camera3_stream_configuration which can be populated * by clients with initial values for the keys found in ANDROID_REQUEST_AVAILABLE_SESSION_KEYS. + * + * - Metadata additions for logical multi camera capability: + * - ANDROID_REQUEST_AVAILABLE_CAPABILITIES_LOGICAL_MULTI_CAMERA + * - ANDROID_LOGICAL_MULTI_CAMERA_PHYSICAL_IDS + * - ANDROID_LOGICAL_MULTI_CAMERA_SYNC_TYPE + * + * - Add physical camera id field in camera3_stream, so that for a logical + * multi camera, the application has the option to specify which physical camera + * a particular stream is configured on. */ /** @@ -1699,8 +1708,31 @@ typedef struct camera3_stream { */ int rotation; + /** + * The physical camera id this stream belongs to. + * + * <= CAMERA_DEVICE_API_VERISON_3_4: + * + * Not defined and must not be accessed. + * + * >= CAMERA_DEVICE_API_VERISON_3_5: + * + * Always set by camera service. If the camera device is not a logical + * multi camera, or if the camera is a logical multi camera but the stream + * is not a physical output stream, this field will point to a 0-length + * string. + * + * A logical multi camera is a camera device backed by multiple physical + * cameras that are also exposed to the application. And for a logical + * multi camera, a physical output stream is an output stream specifically + * requested on an underlying physical camera. + * + * For an input stream, this field is guaranteed to be a 0-length string. + */ + const char* physical_camera_id; + /* reserved for future use */ - void *reserved[7]; + void *reserved[6]; } camera3_stream_t; From 92261ffa2e7c40c5213574d50753c96b34da0d16 Mon Sep 17 00:00:00 2001 From: Emilian Peev Date: Tue, 16 Jan 2018 15:01:22 +0000 Subject: [PATCH 21/50] camera3: Extend camera capture request for multiple cameras The legacy camera 3.5 API should allow clients to set individual settings for specific physical cameras that are part of a logical multi-camera. 'camera3_capture_request_t' must include additional arrays containing the required settings and corresponding camera ids. Test: Manual using camera application, camera_client_test Bug: 64691172 Change-Id: I634f1d5b87a6d97c5a35b8ea633c7a6c22793eaf --- include/hardware/camera3.h | 45 +++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index d140ae05..53e8d7b7 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -178,6 +178,10 @@ * - Add physical camera id field in camera3_stream, so that for a logical * multi camera, the application has the option to specify which physical camera * a particular stream is configured on. + * + * - Add physical camera id and settings field in camera3_capture_request, so that + * for a logical multi camera, the application has the option to specify individual + * settings for a particular physical device. */ /** @@ -2273,6 +2277,44 @@ typedef struct camera3_capture_request { */ const camera3_stream_buffer_t *output_buffers; + /** + * <= CAMERA_DEVICE_API_VERISON_3_4: + * + * Not defined and must not be accessed. + * + * >= CAMERA_DEVICE_API_VERSION_3_5: + * The number of physical camera settings to be applied. If 'num_physcam_settings' + * equals 0 or a physical device is not included, then Hal must decide the + * specific physical device settings based on the default 'settings'. + */ + uint32_t num_physcam_settings; + + /** + * <= CAMERA_DEVICE_API_VERISON_3_4: + * + * Not defined and must not be accessed. + * + * >= CAMERA_DEVICE_API_VERSION_3_5: + * The physical camera ids. The array will contain 'num_physcam_settings' + * camera id strings for all physical devices that have specific settings. + * In case some id is invalid, the process capture request must fail and return + * -EINVAL. + */ + const char **physcam_id; + + /** + * <= CAMERA_DEVICE_API_VERISON_3_4: + * + * Not defined and must not be accessed. + * + * >= CAMERA_DEVICE_API_VERSION_3_5: + * The capture settings for the physical cameras. The array will contain + * 'num_physcam_settings' settings for invididual physical devices. In + * case the settings at some particular index are empty, the process capture + * request must fail and return -EINVAL. + */ + const camera_metadata_t **physcam_settings; + } camera3_capture_request_t; /** @@ -2982,7 +3024,8 @@ typedef struct camera3_device_ops { * 0: On a successful start to processing the capture request * * -EINVAL: If the input is malformed (the settings are NULL when not - * allowed, there are 0 output buffers, etc) and capture processing + * allowed, invalid physical camera settings, + * there are 0 output buffers, etc) and capture processing * cannot start. Failures during request processing should be * handled by calling camera3_callback_ops_t.notify(). In case of * this error, the framework will retain responsibility for the From fc9e212f018ce41430ec8dcebc3cae3c346474bb Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Wed, 17 Jan 2018 15:57:40 -0800 Subject: [PATCH 22/50] Audio V4: Split system and vendor Audio.h audio.h and its dependencies (audio-effect.h, sound_trigger.h...) used to be shared between system and vendor code. This led to multiple problems: 1) Such sharing contradicts the Treble policy of strict independence of framework and vendor code. 2) When audio.h was changed, every vendor needed to update its code in the next release. This meant that audio*.h headers were mostly changed in backward compatible manner. Nevertheless, for P the HIDL interface and thus the audio.h interface are changed in backward incompatible way. (Some enum are becoming 64 bit long). 3) As the headers were common, some API used only by the framework needed to be visible to the vendors (mostly enum values). 4) Treble policy is to support at least one previous HAL version As a result the audio*.h headers are now duplicated, one set for the framework, and one for the vendor. Each set will evolve independently. After this split, the framework-only APIs will be removed from the vendor headers and vice versa. The split is implements as such: + for system code - NOT moving the libaudio_system_headers Eg: system/audio.h and system/audio_effects/effect_equalizer.h are still in system/media/audio - the legacy audio HAL API that were in libhardware headers are now in libaudiohal_legacy_headers Eg: hardware/audio.h and hardware/audio_effect.h are now in frameworks/av/media/libaudiohal/legacy/ + for vendor code - moving libaudio_system_headers and the legacy audio HAL API that were in libhardware_headers in android.hardware.audio.common.legacy@2.0 Note that those headers are now versioned, so migrating to a @4.0 HIDL HAL will mean changing the legacy dependency too. Eg: system/audio.h, system/audio-effect.h, hardware/audio.h are now in hardware/interfaces/audio/common/2.0/legacy - the legacy audio effect HAL API that was in libaudioeffects is now moved in android.hardware.audio.effect.legacy@2.0 Eg: audio_effects/effect*.h are now in hardware/interfaces/audio/effect/2.0/legacy - the legacy sound trigger HAL API that were in libhardware_headers is now moved in android.hardware.soundtrigger.legacy@2.0 Eg: hardware/sound_trigger.h is now in hardware/interfaces/audio/effect/2.0/legacy libaudioutil being used by both system and vendor, had to be renamed for system to libaudioutil_system. Vendor libs that now depend on the audio.h of a specific version and are not extensively referenced in non google code, append @2.0 to their name. Note that headers that are not expected to change in the 4.0 HAL are left in all-versions folder to avoid duplication. This is an implementation detail as the versioned libraries export the all-versions headers. Note that strict vendor-system separation is enforced by the build-system. The system headers are not available for vendor libs and vice-versa. Note that this patch is split between numerous git repository (>10), all the commits having the same Change-id for searchability. Note that audio_policy.h is no longer exposed to vendors as the legacy audio policy HAL API was never officially supported. As a result the audiopolicy stub implementation has been removed. Test: compile taimen-userdebug walleye-userdebug sailfish-userdebug marlin-userdebug gce_x86_phone-userdebug gce_x86_phone full-eng aosp_arm aosp_x86-eng Test: check that the emulator booted and played audio Test: full QA on sailfish-userdebug and taimen-userdebug Bug: 38184704 Change-Id: I950f4e0a55613d72e32eba31bd563cb5bafe2d1a Signed-off-by: Kevin Rocard --- Android.bp | 2 - include/hardware/audio.h | 745 ------------------------- include/hardware/audio_alsaops.h | 103 ---- include/hardware/audio_effect.h | 310 ---------- include/hardware/audio_policy.h | 457 --------------- modules/audio/Android.bp | 24 +- modules/audio/audio_policy.c | 350 ------------ modules/audio_remote_submix/Android.bp | 9 +- modules/usbaudio/Android.bp | 4 +- 9 files changed, 15 insertions(+), 1989 deletions(-) delete mode 100644 include/hardware/audio.h delete mode 100644 include/hardware/audio_alsaops.h delete mode 100644 include/hardware/audio_effect.h delete mode 100644 include/hardware/audio_policy.h delete mode 100644 modules/audio/audio_policy.c diff --git a/Android.bp b/Android.bp index 4766b71d..fd138b01 100644 --- a/Android.bp +++ b/Android.bp @@ -3,13 +3,11 @@ cc_library_headers { name: "libhardware_headers", header_libs: [ - "libaudio_system_headers", "libsystem_headers", "libcutils_headers", "libbluetooth-types-header", ], export_header_lib_headers: [ - "libaudio_system_headers", "libsystem_headers", "libcutils_headers", "libbluetooth-types-header", diff --git a/include/hardware/audio.h b/include/hardware/audio.h deleted file mode 100644 index 2d6eb309..00000000 --- a/include/hardware/audio.h +++ /dev/null @@ -1,745 +0,0 @@ -/* - * Copyright (C) 2011 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_AUDIO_HAL_INTERFACE_H -#define ANDROID_AUDIO_HAL_INTERFACE_H - -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -__BEGIN_DECLS - -/** - * The id of this module - */ -#define AUDIO_HARDWARE_MODULE_ID "audio" - -/** - * Name of the audio devices to open - */ -#define AUDIO_HARDWARE_INTERFACE "audio_hw_if" - - -/* Use version 0.1 to be compatible with first generation of audio hw module with version_major - * hardcoded to 1. No audio module API change. - */ -#define AUDIO_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) -#define AUDIO_MODULE_API_VERSION_CURRENT AUDIO_MODULE_API_VERSION_0_1 - -/* First generation of audio devices had version hardcoded to 0. all devices with versions < 1.0 - * will be considered of first generation API. - */ -#define AUDIO_DEVICE_API_VERSION_0_0 HARDWARE_DEVICE_API_VERSION(0, 0) -#define AUDIO_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) -#define AUDIO_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) -#define AUDIO_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) -#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_0 -/* Minimal audio HAL version supported by the audio framework */ -#define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0 - -/**************************************/ - -/** - * standard audio parameters that the HAL may need to handle - */ - -/** - * audio device parameters - */ - -/* TTY mode selection */ -#define AUDIO_PARAMETER_KEY_TTY_MODE "tty_mode" -#define AUDIO_PARAMETER_VALUE_TTY_OFF "tty_off" -#define AUDIO_PARAMETER_VALUE_TTY_VCO "tty_vco" -#define AUDIO_PARAMETER_VALUE_TTY_HCO "tty_hco" -#define AUDIO_PARAMETER_VALUE_TTY_FULL "tty_full" - -/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off */ -#define AUDIO_PARAMETER_KEY_HAC "HACSetting" -#define AUDIO_PARAMETER_VALUE_HAC_ON "ON" -#define AUDIO_PARAMETER_VALUE_HAC_OFF "OFF" - -/* A2DP sink address set by framework */ -#define AUDIO_PARAMETER_A2DP_SINK_ADDRESS "a2dp_sink_address" - -/* A2DP source address set by framework */ -#define AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS "a2dp_source_address" - -/* Bluetooth SCO wideband */ -#define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs" - -/** - * audio stream parameters - */ - -/* Enable AANC */ -#define AUDIO_PARAMETER_KEY_AANC "aanc_enabled" - -/**************************************/ - -/* common audio stream parameters and operations */ -struct audio_stream { - - /** - * Return the sampling rate in Hz - eg. 44100. - */ - uint32_t (*get_sample_rate)(const struct audio_stream *stream); - - /* currently unused - use set_parameters with key - * AUDIO_PARAMETER_STREAM_SAMPLING_RATE - */ - int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); - - /** - * Return size of input/output buffer in bytes for this stream - eg. 4800. - * It should be a multiple of the frame size. See also get_input_buffer_size. - */ - size_t (*get_buffer_size)(const struct audio_stream *stream); - - /** - * Return the channel mask - - * e.g. AUDIO_CHANNEL_OUT_STEREO or AUDIO_CHANNEL_IN_STEREO - */ - audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); - - /** - * Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT - */ - audio_format_t (*get_format)(const struct audio_stream *stream); - - /* currently unused - use set_parameters with key - * AUDIO_PARAMETER_STREAM_FORMAT - */ - int (*set_format)(struct audio_stream *stream, audio_format_t format); - - /** - * Put the audio hardware input/output into standby mode. - * Driver should exit from standby mode at the next I/O operation. - * Returns 0 on success and <0 on failure. - */ - int (*standby)(struct audio_stream *stream); - - /** dump the state of the audio input/output device */ - int (*dump)(const struct audio_stream *stream, int fd); - - /** Return the set of device(s) which this stream is connected to */ - audio_devices_t (*get_device)(const struct audio_stream *stream); - - /** - * Currently unused - set_device() corresponds to set_parameters() with key - * AUDIO_PARAMETER_STREAM_ROUTING for both input and output. - * AUDIO_PARAMETER_STREAM_INPUT_SOURCE is an additional information used by - * input streams only. - */ - int (*set_device)(struct audio_stream *stream, audio_devices_t device); - - /** - * set/get audio stream parameters. The function accepts a list of - * parameter key value pairs in the form: key1=value1;key2=value2;... - * - * Some keys are reserved for standard parameters (See AudioParameter class) - * - * If the implementation does not accept a parameter change while - * the output is active but the parameter is acceptable otherwise, it must - * return -ENOSYS. - * - * The audio flinger will put the stream in standby and then change the - * parameter value. - */ - int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); - - /* - * Returns a pointer to a heap allocated string. The caller is responsible - * for freeing the memory for it using free(). - */ - char * (*get_parameters)(const struct audio_stream *stream, - const char *keys); - int (*add_audio_effect)(const struct audio_stream *stream, - effect_handle_t effect); - int (*remove_audio_effect)(const struct audio_stream *stream, - effect_handle_t effect); -}; -typedef struct audio_stream audio_stream_t; - -/* 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_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); - -/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */ -typedef enum { - AUDIO_DRAIN_ALL, /* drain() returns when all data has been played */ - AUDIO_DRAIN_EARLY_NOTIFY /* drain() returns a short time before all data - from the current track has been played to - give time for gapless track switch */ -} audio_drain_type_t; - -/** - * audio_stream_out is the abstraction interface for the audio output hardware. - * - * It provides information about various properties of the audio output - * hardware driver. - */ - -struct audio_stream_out { - /** - * Common methods of the audio stream out. This *must* be the first member of audio_stream_out - * as users of this structure will cast a audio_stream to audio_stream_out pointer in contexts - * where it's known the audio_stream references an audio_stream_out. - */ - struct audio_stream common; - - /** - * Return the audio hardware driver estimated latency in milliseconds. - */ - uint32_t (*get_latency)(const struct audio_stream_out *stream); - - /** - * Use this method in situations where audio mixing is done in the - * hardware. This method serves as a direct interface with hardware, - * allowing you to directly set the volume as apposed to via the framework. - * This method might produce multiple PCM outputs or hardware accelerated - * codecs, such as MP3 or AAC. - */ - int (*set_volume)(struct audio_stream_out *stream, float left, float right); - - /** - * Write audio buffer to driver. Returns number of bytes written, or a - * negative status_t. If at least one frame was written successfully prior to the error, - * it is suggested that the driver return that successful (short) byte count - * and then return an error in the subsequent call. - * - * If set_callback() has previously been called to enable non-blocking mode - * the write() is not allowed to block. It must write only the number of - * bytes that currently fit in the driver/hardware buffer and then return - * this byte count. If this is less than the requested write size the - * callback function must be called when more space is available in the - * driver/hardware buffer. - */ - ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, - size_t bytes); - - /* return the number of audio frames written by the audio dsp to DAC since - * the output has exited standby - */ - int (*get_render_position)(const struct audio_stream_out *stream, - uint32_t *dsp_frames); - - /** - * get the local time at which the next write to the audio driver will be presented. - * The units are microseconds, where the epoch is decided by the local audio HAL. - */ - int (*get_next_write_timestamp)(const struct audio_stream_out *stream, - int64_t *timestamp); - - /** - * set the callback function for notifying completion of non-blocking - * write and drain. - * Calling this function implies that all future write() and drain() - * must be non-blocking and use the callback to signal completion. - */ - int (*set_callback)(struct audio_stream_out *stream, - stream_callback_t callback, void *cookie); - - /** - * Notifies to the audio driver to stop playback however the queued buffers are - * retained by the hardware. Useful for implementing pause/resume. Empty implementation - * if not supported however should be implemented for hardware with non-trivial - * latency. In the pause state audio hardware could still be using power. User may - * consider calling suspend after a timeout. - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*pause)(struct audio_stream_out* stream); - - /** - * Notifies to the audio driver to resume playback following a pause. - * Returns error if called without matching pause. - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*resume)(struct audio_stream_out* stream); - - /** - * Requests notification when data buffered by the driver/hardware has - * been played. If set_callback() has previously been called to enable - * non-blocking mode, the drain() must not block, instead it should return - * quickly and completion of the drain is notified through the callback. - * If set_callback() has not been called, the drain() must block until - * completion. - * If type==AUDIO_DRAIN_ALL, the drain completes when all previously written - * data has been played. - * If type==AUDIO_DRAIN_EARLY_NOTIFY, the drain completes shortly before all - * data for the current track has played to allow time for the framework - * to perform a gapless track switch. - * - * Drain must return immediately on stop() and flush() call - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type ); - - /** - * Notifies to the audio driver to flush the queued data. Stream must already - * be paused before calling flush(). - * - * Implementation of this function is mandatory for offloaded playback. - */ - int (*flush)(struct audio_stream_out* stream); - - /** - * Return a recent count of the number of audio frames presented to an external observer. - * This excludes frames which have been written but are still in the pipeline. - * The count is not reset to zero when output enters standby. - * Also returns the value of CLOCK_MONOTONIC as of this presentation count. - * The returned count is expected to be 'recent', - * but does not need to be the most recent possible value. - * However, the associated time should correspond to whatever count is returned. - * Example: assume that N+M frames have been presented, where M is a 'small' number. - * Then it is permissible to return N instead of N+M, - * and the timestamp should correspond to N rather than N+M. - * The terms 'recent' and 'small' are not defined. - * They reflect the quality of the implementation. - * - * 3.0 and higher only. - */ - int (*get_presentation_position)(const struct audio_stream_out *stream, - uint64_t *frames, struct timespec *timestamp); - - /** - * Called by the framework to start a stream operating in mmap mode. - * create_mmap_buffer must be called before calling start() - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \return 0 in case of success. - * -ENOSYS if called out of sequence or on non mmap stream - */ - int (*start)(const struct audio_stream_out* stream); - - /** - * Called by the framework to stop a stream operating in mmap mode. - * Must be called after start() - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \return 0 in case of success. - * -ENOSYS if called out of sequence or on non mmap stream - */ - int (*stop)(const struct audio_stream_out* stream); - - /** - * Called by the framework to retrieve information on the mmap buffer used for audio - * samples transfer. - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \param[in] min_size_frames minimum buffer size requested. The actual buffer - * size returned in struct audio_mmap_buffer_info can be larger. - * \param[out] info address at which the mmap buffer information should be returned. - * - * \return 0 if the buffer was allocated. - * -ENODEV in case of initialization error - * -EINVAL if the requested buffer size is too large - * -ENOSYS if called out of sequence (e.g. buffer already allocated) - */ - int (*create_mmap_buffer)(const struct audio_stream_out *stream, - int32_t min_size_frames, - struct audio_mmap_buffer_info *info); - - /** - * Called by the framework to read current read/write position in the mmap buffer - * with associated time stamp. - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \param[out] position address at which the mmap read/write position should be returned. - * - * \return 0 if the position is successfully returned. - * -ENODATA if the position cannot be retrieved - * -ENOSYS if called before create_mmap_buffer() - */ - int (*get_mmap_position)(const struct audio_stream_out *stream, - struct audio_mmap_position *position); -}; -typedef struct audio_stream_out audio_stream_out_t; - -struct audio_stream_in { - /** - * Common methods of the audio stream in. This *must* be the first member of audio_stream_in - * as users of this structure will cast a audio_stream to audio_stream_in pointer in contexts - * where it's known the audio_stream references an audio_stream_in. - */ - struct audio_stream common; - - /** set the input gain for the audio driver. This method is for - * for future use */ - int (*set_gain)(struct audio_stream_in *stream, float gain); - - /** Read audio buffer in from audio driver. Returns number of bytes read, or a - * negative status_t. If at least one frame was read prior to the error, - * read should return that byte count and then return an error in the subsequent call. - */ - ssize_t (*read)(struct audio_stream_in *stream, void* buffer, - size_t bytes); - - /** - * Return the amount of input frames lost in the audio driver since the - * last call of this function. - * Audio driver is expected to reset the value to 0 and restart counting - * upon returning the current value by this function call. - * Such loss typically occurs when the user space process is blocked - * longer than the capacity of audio driver buffers. - * - * Unit: the number of input audio frames - */ - uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream); - - /** - * Return a recent count of the number of audio frames received and - * the clock time associated with that frame count. - * - * frames is the total frame count received. This should be as early in - * the capture pipeline as possible. In general, - * frames should be non-negative and should not go "backwards". - * - * time is the clock MONOTONIC time when frames was measured. In general, - * time should be a positive quantity and should not go "backwards". - * - * The status returned is 0 on success, -ENOSYS if the device is not - * ready/available, or -EINVAL if the arguments are null or otherwise invalid. - */ - int (*get_capture_position)(const struct audio_stream_in *stream, - int64_t *frames, int64_t *time); - - /** - * Called by the framework to start a stream operating in mmap mode. - * create_mmap_buffer must be called before calling start() - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \return 0 in case off success. - * -ENOSYS if called out of sequence or on non mmap stream - */ - int (*start)(const struct audio_stream_in* stream); - - /** - * Called by the framework to stop a stream operating in mmap mode. - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \return 0 in case of success. - * -ENOSYS if called out of sequence or on non mmap stream - */ - int (*stop)(const struct audio_stream_in* stream); - - /** - * Called by the framework to retrieve information on the mmap buffer used for audio - * samples transfer. - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \param[in] min_size_frames minimum buffer size requested. The actual buffer - * size returned in struct audio_mmap_buffer_info can be larger. - * \param[out] info address at which the mmap buffer information should be returned. - * - * \return 0 if the buffer was allocated. - * -ENODEV in case of initialization error - * -EINVAL if the requested buffer size is too large - * -ENOSYS if called out of sequence (e.g. buffer already allocated) - */ - int (*create_mmap_buffer)(const struct audio_stream_in *stream, - int32_t min_size_frames, - struct audio_mmap_buffer_info *info); - - /** - * Called by the framework to read current read/write position in the mmap buffer - * with associated time stamp. - * - * \note Function only implemented by streams operating in mmap mode. - * - * \param[in] stream the stream object. - * \param[out] position address at which the mmap read/write position should be returned. - * - * \return 0 if the position is successfully returned. - * -ENODATA if the position cannot be retreived - * -ENOSYS if called before mmap_read_position() - */ - int (*get_mmap_position)(const struct audio_stream_in *stream, - struct audio_mmap_position *position); -}; -typedef struct audio_stream_in audio_stream_in_t; - -/** - * return the frame size (number of bytes per sample). - * - * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead. - */ -__attribute__((__deprecated__)) -static inline size_t audio_stream_frame_size(const struct audio_stream *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->get_format(s); - - if (audio_has_proportional_frames(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return popcount(s->get_channels(s)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/** - * return the frame size (number of bytes per sample) of an output stream. - */ -static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->common.get_format(&s->common); - - if (audio_has_proportional_frames(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/** - * return the frame size (number of bytes per sample) of an input stream. - */ -static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s) -{ - size_t chan_samp_sz; - audio_format_t format = s->common.get_format(&s->common); - - if (audio_has_proportional_frames(format)) { - chan_samp_sz = audio_bytes_per_sample(format); - return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz; - } - - return sizeof(int8_t); -} - -/**********************************************************************/ - -/** - * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM - * and the fields of this data structure must begin with hw_module_t - * followed by module specific information. - */ -struct audio_module { - struct hw_module_t common; -}; - -struct audio_hw_device { - /** - * Common methods of the audio device. This *must* be the first member of audio_hw_device - * as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts - * where it's known the hw_device_t references an audio_hw_device. - */ - struct hw_device_t common; - - /** - * used by audio flinger to enumerate what devices are supported by - * each audio_hw_device implementation. - * - * Return value is a bitmask of 1 or more values of audio_devices_t - * - * NOTE: audio HAL implementations starting with - * AUDIO_DEVICE_API_VERSION_2_0 do not implement this function. - * All supported devices should be listed in audio_policy.conf - * file and the audio policy manager must choose the appropriate - * audio module based on information in this file. - */ - uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); - - /** - * check to see if the audio hardware interface has been initialized. - * returns 0 on success, -ENODEV on failure. - */ - int (*init_check)(const struct audio_hw_device *dev); - - /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ - int (*set_voice_volume)(struct audio_hw_device *dev, float volume); - - /** - * set the audio volume for all audio activities other than voice call. - * Range between 0.0 and 1.0. If any value other than 0 is returned, - * the software mixer will emulate this capability. - */ - int (*set_master_volume)(struct audio_hw_device *dev, float volume); - - /** - * Get the current master volume value for the HAL, if the HAL supports - * master volume control. AudioFlinger will query this value from the - * primary audio HAL when the service starts and use the value for setting - * the initial master volume across all HALs. HALs which do not support - * this method may leave it set to NULL. - */ - int (*get_master_volume)(struct audio_hw_device *dev, float *volume); - - /** - * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode - * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is - * playing, and AUDIO_MODE_IN_CALL when a call is in progress. - */ - int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); - - /* mic mute */ - int (*set_mic_mute)(struct audio_hw_device *dev, bool state); - int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); - - /* set/get global audio parameters */ - int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); - - /* - * Returns a pointer to a heap allocated string. The caller is responsible - * for freeing the memory for it using free(). - */ - char * (*get_parameters)(const struct audio_hw_device *dev, - const char *keys); - - /* Returns audio input buffer size according to parameters passed or - * 0 if one of the parameters is not supported. - * See also get_buffer_size which is for a particular stream. - */ - size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, - const struct audio_config *config); - - /** This method creates and opens the audio hardware output stream. - * The "address" parameter qualifies the "devices" audio device type if needed. - * The format format depends on the device type: - * - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC" - * - USB devices use the ALSA card and device numbers in the form "card=X;device=Y" - * - Other devices may use a number or any other string. - */ - - int (*open_output_stream)(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - audio_output_flags_t flags, - struct audio_config *config, - struct audio_stream_out **stream_out, - const char *address); - - void (*close_output_stream)(struct audio_hw_device *dev, - struct audio_stream_out* stream_out); - - /** This method creates and opens the audio hardware input stream */ - int (*open_input_stream)(struct audio_hw_device *dev, - audio_io_handle_t handle, - audio_devices_t devices, - struct audio_config *config, - struct audio_stream_in **stream_in, - audio_input_flags_t flags, - const char *address, - audio_source_t source); - - void (*close_input_stream)(struct audio_hw_device *dev, - struct audio_stream_in *stream_in); - - /** This method dumps the state of the audio hardware */ - int (*dump)(const struct audio_hw_device *dev, int fd); - - /** - * set the audio mute status for all audio activities. If any value other - * than 0 is returned, the software mixer will emulate this capability. - */ - int (*set_master_mute)(struct audio_hw_device *dev, bool mute); - - /** - * Get the current master mute status for the HAL, if the HAL supports - * master mute control. AudioFlinger will query this value from the primary - * audio HAL when the service starts and use the value for setting the - * initial master mute across all HALs. HALs which do not support this - * method may leave it set to NULL. - */ - int (*get_master_mute)(struct audio_hw_device *dev, bool *mute); - - /** - * Routing control - */ - - /* Creates an audio patch between several source and sink ports. - * The handle is allocated by the HAL and should be unique for this - * audio HAL module. */ - int (*create_audio_patch)(struct audio_hw_device *dev, - unsigned int num_sources, - const struct audio_port_config *sources, - unsigned int num_sinks, - const struct audio_port_config *sinks, - audio_patch_handle_t *handle); - - /* Release an audio patch */ - int (*release_audio_patch)(struct audio_hw_device *dev, - audio_patch_handle_t handle); - - /* Fills the list of supported attributes for a given audio port. - * As input, "port" contains the information (type, role, address etc...) - * needed by the HAL to identify the port. - * As output, "port" contains possible attributes (sampling rates, formats, - * channel masks, gain controllers...) for this port. - */ - int (*get_audio_port)(struct audio_hw_device *dev, - struct audio_port *port); - - /* Set audio port configuration */ - int (*set_audio_port_config)(struct audio_hw_device *dev, - const struct audio_port_config *config); - -}; -typedef struct audio_hw_device audio_hw_device_t; - -/** convenience API for opening and closing a supported device */ - -static inline int audio_hw_device_open(const struct hw_module_t* module, - struct audio_hw_device** device) -{ - return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, - TO_HW_DEVICE_T_OPEN(device)); -} - -static inline int audio_hw_device_close(struct audio_hw_device* device) -{ - return device->common.close(&device->common); -} - - -__END_DECLS - -#endif // ANDROID_AUDIO_INTERFACE_H diff --git a/include/hardware/audio_alsaops.h b/include/hardware/audio_alsaops.h deleted file mode 100644 index 6a17a351..00000000 --- a/include/hardware/audio_alsaops.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2014 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. - */ - -/* This file contains shared utility functions to handle the tinyalsa - * implementation for Android internal audio, generally in the hardware layer. - * Some routines may log a fatal error on failure, as noted. - */ - -#ifndef ANDROID_AUDIO_ALSAOPS_H -#define ANDROID_AUDIO_ALSAOPS_H - -#include - -#include -#include - -__BEGIN_DECLS - -/* Converts audio_format to pcm_format. - * Parameters: - * format the audio_format_t to convert - * - * Logs a fatal error if format is not a valid convertible audio_format_t. - */ -static inline enum pcm_format pcm_format_from_audio_format(audio_format_t format) -{ - switch (format) { -#if HAVE_BIG_ENDIAN - case AUDIO_FORMAT_PCM_16_BIT: - return PCM_FORMAT_S16_BE; - case AUDIO_FORMAT_PCM_24_BIT_PACKED: - return PCM_FORMAT_S24_3BE; - case AUDIO_FORMAT_PCM_32_BIT: - return PCM_FORMAT_S32_BE; - case AUDIO_FORMAT_PCM_8_24_BIT: - return PCM_FORMAT_S24_BE; -#else - case AUDIO_FORMAT_PCM_16_BIT: - return PCM_FORMAT_S16_LE; - case AUDIO_FORMAT_PCM_24_BIT_PACKED: - return PCM_FORMAT_S24_3LE; - case AUDIO_FORMAT_PCM_32_BIT: - return PCM_FORMAT_S32_LE; - case AUDIO_FORMAT_PCM_8_24_BIT: - return PCM_FORMAT_S24_LE; -#endif - case AUDIO_FORMAT_PCM_FLOAT: /* there is no equivalent for float */ - default: - LOG_ALWAYS_FATAL("pcm_format_from_audio_format: invalid audio format %#x", format); - return 0; - } -} - -/* Converts pcm_format to audio_format. - * Parameters: - * format the pcm_format to convert - * - * Logs a fatal error if format is not a valid convertible pcm_format. - */ -static inline audio_format_t audio_format_from_pcm_format(enum pcm_format format) -{ - switch (format) { -#if HAVE_BIG_ENDIAN - case PCM_FORMAT_S16_BE: - return AUDIO_FORMAT_PCM_16_BIT; - case PCM_FORMAT_S24_3BE: - return AUDIO_FORMAT_PCM_24_BIT_PACKED; - case PCM_FORMAT_S24_BE: - return AUDIO_FORMAT_PCM_8_24_BIT; - case PCM_FORMAT_S32_BE: - return AUDIO_FORMAT_PCM_32_BIT; -#else - case PCM_FORMAT_S16_LE: - return AUDIO_FORMAT_PCM_16_BIT; - case PCM_FORMAT_S24_3LE: - return AUDIO_FORMAT_PCM_24_BIT_PACKED; - case PCM_FORMAT_S24_LE: - return AUDIO_FORMAT_PCM_8_24_BIT; - case PCM_FORMAT_S32_LE: - return AUDIO_FORMAT_PCM_32_BIT; -#endif - default: - LOG_ALWAYS_FATAL("audio_format_from_pcm_format: invalid pcm format %#x", format); - return 0; - } -} - -__END_DECLS - -#endif /* ANDROID_AUDIO_ALSAOPS_H */ diff --git a/include/hardware/audio_effect.h b/include/hardware/audio_effect.h deleted file mode 100644 index 3366e178..00000000 --- a/include/hardware/audio_effect.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright (C) 2011 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_AUDIO_EFFECT_H -#define ANDROID_AUDIO_EFFECT_H - -#include -#include -#include -#include -#include - -#include - -#include - - -__BEGIN_DECLS - - -///////////////////////////////////////////////// -// Common Definitions -///////////////////////////////////////////////// - -#define EFFECT_MAKE_API_VERSION(M, m) (((M)<<16) | ((m) & 0xFFFF)) -#define EFFECT_API_VERSION_MAJOR(v) ((v)>>16) -#define EFFECT_API_VERSION_MINOR(v) ((m) & 0xFFFF) - - -///////////////////////////////////////////////// -// Effect control interface -///////////////////////////////////////////////// - -// Effect control interface version 2.0 -#define EFFECT_CONTROL_API_VERSION EFFECT_MAKE_API_VERSION(2,0) - -// Effect control interface structure: effect_interface_s -// The effect control interface is exposed by each effect engine implementation. It consists of -// a set of functions controlling the configuration, activation and process of the engine. -// The functions are grouped in a structure of type effect_interface_s. -// -// Effect control interface handle: effect_handle_t -// The effect_handle_t serves two purposes regarding the implementation of the effect engine: -// - 1 it is the address of a pointer to an effect_interface_s structure where the functions -// of the effect control API for a particular effect are located. -// - 2 it is the address of the context of a particular effect instance. -// A typical implementation in the effect library would define a structure as follows: -// struct effect_module_s { -// const struct effect_interface_s *itfe; -// effect_config_t config; -// effect_context_t context; -// } -// The implementation of EffectCreate() function would then allocate a structure of this -// type and return its address as effect_handle_t -typedef struct effect_interface_s **effect_handle_t; - -// Effect control interface definition -struct effect_interface_s { - //////////////////////////////////////////////////////////////////////////////// - // - // Function: process - // - // Description: Effect process function. Takes input samples as specified - // (count and location) in input buffer descriptor and output processed - // samples as specified in output buffer descriptor. If the buffer descriptor - // is not specified the function must use either the buffer or the - // buffer provider function installed by the EFFECT_CMD_SET_CONFIG command. - // The effect framework will call the process() function after the EFFECT_CMD_ENABLE - // command is received and until the EFFECT_CMD_DISABLE is received. When the engine - // receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully - // and when done indicate that it is OK to stop calling the process() function by - // returning the -ENODATA status. - // - // NOTE: the process() function implementation should be "real-time safe" that is - // it should not perform blocking calls: malloc/free, sleep, read/write/open/close, - // pthread_cond_wait/pthread_mutex_lock... - // - // Input: - // self: handle to the effect interface this function - // is called on. - // inBuffer: buffer descriptor indicating where to read samples to process. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. - // - // outBuffer: buffer descriptor indicating where to write processed samples. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. - // - // Output: - // returned value: 0 successful operation - // -ENODATA the engine has finished the disable phase and the framework - // can stop calling process() - // -EINVAL invalid interface handle or - // invalid input/output buffer description - //////////////////////////////////////////////////////////////////////////////// - int32_t (*process)(effect_handle_t self, - audio_buffer_t *inBuffer, - audio_buffer_t *outBuffer); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: command - // - // Description: Send a command and receive a response to/from effect engine. - // - // Input: - // self: handle to the effect interface this function - // is called on. - // cmdCode: command code: the command can be a standardized command defined in - // effect_command_e (see below) or a proprietary command. - // cmdSize: size of command in bytes - // pCmdData: pointer to command data - // pReplyData: pointer to reply data - // - // Input/Output: - // replySize: maximum size of reply data as input - // actual size of reply data as output - // - // Output: - // returned value: 0 successful operation - // -EINVAL invalid interface handle or - // invalid command/reply size or format according to - // command code - // The return code should be restricted to indicate problems related to this API - // specification. Status related to the execution of a particular command should be - // indicated as part of the reply field. - // - // *pReplyData updated with command response - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*command)(effect_handle_t self, - uint32_t cmdCode, - uint32_t cmdSize, - void *pCmdData, - uint32_t *replySize, - void *pReplyData); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: get_descriptor - // - // Description: Returns the effect descriptor - // - // Input: - // self: handle to the effect interface this function - // is called on. - // - // Input/Output: - // pDescriptor: address where to return the effect descriptor. - // - // Output: - // returned value: 0 successful operation. - // -EINVAL invalid interface handle or invalid pDescriptor - // *pDescriptor: updated with the effect descriptor. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*get_descriptor)(effect_handle_t self, - effect_descriptor_t *pDescriptor); - //////////////////////////////////////////////////////////////////////////////// - // - // Function: process_reverse - // - // Description: Process reverse stream function. This function is used to pass - // a reference stream to the effect engine. If the engine does not need a reference - // stream, this function pointer can be set to NULL. - // This function would typically implemented by an Echo Canceler. - // - // Input: - // self: handle to the effect interface this function - // is called on. - // inBuffer: buffer descriptor indicating where to read samples to process. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. - // - // outBuffer: buffer descriptor indicating where to write processed samples. - // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. - // If the buffer and buffer provider in the configuration received by - // EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse - // stream data - // - // Output: - // returned value: 0 successful operation - // -ENODATA the engine has finished the disable phase and the framework - // can stop calling process_reverse() - // -EINVAL invalid interface handle or - // invalid input/output buffer description - //////////////////////////////////////////////////////////////////////////////// - int32_t (*process_reverse)(effect_handle_t self, - audio_buffer_t *inBuffer, - audio_buffer_t *outBuffer); -}; - -///////////////////////////////////////////////// -// Effect library interface -///////////////////////////////////////////////// - -// Effect library interface version 3.0 -// Note that EffectsFactory.c only checks the major version component, so changes to the minor -// number can only be used for fully backwards compatible changes -#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(3,0) - -#define AUDIO_EFFECT_LIBRARY_TAG ((('A') << 24) | (('E') << 16) | (('L') << 8) | ('T')) - -// Every effect library must have a data structure named AUDIO_EFFECT_LIBRARY_INFO_SYM -// and the fields of this data structure must begin with audio_effect_library_t - -typedef struct audio_effect_library_s { - // tag must be initialized to AUDIO_EFFECT_LIBRARY_TAG - uint32_t tag; - // Version of the effect library API : 0xMMMMmmmm MMMM: Major, mmmm: minor - uint32_t version; - // Name of this library - const char *name; - // Author/owner/implementor of the library - const char *implementor; - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: create_effect - // - // Description: Creates an effect engine of the specified implementation uuid and - // returns an effect control interface on this engine. The function will allocate the - // resources for an instance of the requested effect engine and return - // a handle on the effect control interface. - // - // Input: - // uuid: pointer to the effect uuid. - // sessionId: audio session to which this effect instance will be attached. - // All effects created with the same session ID are connected in series and process - // the same signal stream. Knowing that two effects are part of the same effect - // chain can help the library implement some kind of optimizations. - // ioId: identifies the output or input stream this effect is directed to in - // audio HAL. - // For future use especially with tunneled HW accelerated effects - // - // Input/Output: - // pHandle: address where to return the effect interface handle. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid pEffectUuid or pHandle - // -ENOENT no effect with this uuid found - // *pHandle: updated with the effect interface handle. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*create_effect)(const effect_uuid_t *uuid, - int32_t sessionId, - int32_t ioId, - effect_handle_t *pHandle); - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: release_effect - // - // Description: Releases the effect engine whose handle is given as argument. - // All resources allocated to this particular instance of the effect are - // released. - // - // Input: - // handle: handle on the effect interface to be released. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid interface handle - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*release_effect)(effect_handle_t handle); - - //////////////////////////////////////////////////////////////////////////////// - // - // Function: get_descriptor - // - // Description: Returns the descriptor of the effect engine which implementation UUID is - // given as argument. - // - // Input/Output: - // uuid: pointer to the effect uuid. - // pDescriptor: address where to return the effect descriptor. - // - // Output: - // returned value: 0 successful operation. - // -ENODEV library failed to initialize - // -EINVAL invalid pDescriptor or uuid - // *pDescriptor: updated with the effect descriptor. - // - //////////////////////////////////////////////////////////////////////////////// - int32_t (*get_descriptor)(const effect_uuid_t *uuid, - effect_descriptor_t *pDescriptor); -} audio_effect_library_t; - -// Name of the hal_module_info -#define AUDIO_EFFECT_LIBRARY_INFO_SYM AELI - -// Name of the hal_module_info as a string -#define AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR "AELI" - -__END_DECLS - -#endif // ANDROID_AUDIO_EFFECT_H diff --git a/include/hardware/audio_policy.h b/include/hardware/audio_policy.h deleted file mode 100644 index bacb1e55..00000000 --- a/include/hardware/audio_policy.h +++ /dev/null @@ -1,457 +0,0 @@ -/* - * Copyright (C) 2011 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_AUDIO_POLICY_INTERFACE_H -#define ANDROID_AUDIO_POLICY_INTERFACE_H - -#include -#include -#include - -#include - -#include -#include - -__BEGIN_DECLS - -/** - * The id of this module - */ -#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy" - -/** - * Name of the audio devices to open - */ -#define AUDIO_POLICY_INTERFACE "policy" - -/* ---------------------------------------------------------------------------- */ - -/* - * The audio_policy and audio_policy_service_ops structs define the - * communication interfaces between the platform specific audio policy manager - * and Android generic audio policy manager. - * The platform specific audio policy manager must implement methods of the - * audio_policy struct. - * This implementation makes use of the audio_policy_service_ops to control - * the activity and configuration of audio input and output streams. - * - * The platform specific audio policy manager is in charge of the audio - * routing and volume control policies for a given platform. - * The main roles of this module are: - * - keep track of current system state (removable device connections, phone - * state, user requests...). - * System state changes and user actions are notified to audio policy - * manager with methods of the audio_policy. - * - * - process get_output() queries received when AudioTrack objects are - * created: Those queries return a handler on an output that has been - * selected, configured and opened by the audio policy manager and that - * must be used by the AudioTrack when registering to the AudioFlinger - * with the createTrack() method. - * When the AudioTrack object is released, a release_output() query - * is received and the audio policy manager can decide to close or - * reconfigure the output depending on other streams using this output and - * current system state. - * - * - similarly process get_input() and release_input() queries received from - * AudioRecord objects and configure audio inputs. - * - process volume control requests: the stream volume is converted from - * an index value (received from UI) to a float value applicable to each - * output as a function of platform specific settings and current output - * route (destination device). It also make sure that streams are not - * muted if not allowed (e.g. camera shutter sound in some countries). - */ - -/* XXX: this should be defined OUTSIDE of frameworks/base */ -struct effect_descriptor_s; - -struct audio_policy { - /* - * configuration functions - */ - - /* indicate a change in device connection status */ - int (*set_device_connection_state)(struct audio_policy *pol, - audio_devices_t device, - audio_policy_dev_state_t state, - const char *device_address); - - /* retrieve a device connection status */ - audio_policy_dev_state_t (*get_device_connection_state)( - const struct audio_policy *pol, - audio_devices_t device, - const char *device_address); - - /* indicate a change in phone state. Valid phones states are defined - * by audio_mode_t */ - void (*set_phone_state)(struct audio_policy *pol, audio_mode_t state); - - /* deprecated, never called (was "indicate a change in ringer mode") */ - void (*set_ringer_mode)(struct audio_policy *pol, uint32_t mode, - uint32_t mask); - - /* force using a specific device category for the specified usage */ - void (*set_force_use)(struct audio_policy *pol, - audio_policy_force_use_t usage, - audio_policy_forced_cfg_t config); - - /* retrieve current device category forced for a given usage */ - audio_policy_forced_cfg_t (*get_force_use)(const struct audio_policy *pol, - audio_policy_force_use_t usage); - - /* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE - * can still be muted. */ - void (*set_can_mute_enforced_audible)(struct audio_policy *pol, - bool can_mute); - - /* check proper initialization */ - int (*init_check)(const struct audio_policy *pol); - - /* - * Audio routing query functions - */ - - /* request an output appropriate for playback of the supplied stream type and - * parameters */ - audio_io_handle_t (*get_output)(struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo); - - /* indicates to the audio policy manager that the output starts being used - * by corresponding stream. */ - int (*start_output)(struct audio_policy *pol, - audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session); - - /* indicates to the audio policy manager that the output stops being used - * by corresponding stream. */ - int (*stop_output)(struct audio_policy *pol, - audio_io_handle_t output, - audio_stream_type_t stream, - audio_session_t session); - - /* releases the output. */ - void (*release_output)(struct audio_policy *pol, audio_io_handle_t output); - - /* request an input appropriate for record from the supplied device with - * supplied parameters. */ - audio_io_handle_t (*get_input)(struct audio_policy *pol, audio_source_t inputSource, - uint32_t samplingRate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_in_acoustics_t acoustics); - - /* indicates to the audio policy manager that the input starts being used */ - int (*start_input)(struct audio_policy *pol, audio_io_handle_t input); - - /* indicates to the audio policy manager that the input stops being used. */ - int (*stop_input)(struct audio_policy *pol, audio_io_handle_t input); - - /* releases the input. */ - void (*release_input)(struct audio_policy *pol, audio_io_handle_t input); - - /* - * volume control functions - */ - - /* initialises stream volume conversion parameters by specifying volume - * index range. The index range for each stream is defined by AudioService. */ - void (*init_stream_volume)(struct audio_policy *pol, - audio_stream_type_t stream, - int index_min, - int index_max); - - /* sets the new stream volume at a level corresponding to the supplied - * index. The index is within the range specified by init_stream_volume() */ - int (*set_stream_volume_index)(struct audio_policy *pol, - audio_stream_type_t stream, - int index); - - /* retrieve current volume index for the specified stream */ - int (*get_stream_volume_index)(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index); - - /* sets the new stream volume at a level corresponding to the supplied - * index for the specified device. - * The index is within the range specified by init_stream_volume() */ - int (*set_stream_volume_index_for_device)(struct audio_policy *pol, - audio_stream_type_t stream, - int index, - audio_devices_t device); - - /* retrieve current volume index for the specified stream for the specified device */ - int (*get_stream_volume_index_for_device)(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index, - audio_devices_t device); - - /* return the strategy corresponding to a given stream type */ - uint32_t (*get_strategy_for_stream)(const struct audio_policy *pol, - audio_stream_type_t stream); - - /* return the enabled output devices for the given stream type */ - audio_devices_t (*get_devices_for_stream)(const struct audio_policy *pol, - audio_stream_type_t stream); - - /* Audio effect management */ - audio_io_handle_t (*get_output_for_effect)(struct audio_policy *pol, - const struct effect_descriptor_s *desc); - - int (*register_effect)(struct audio_policy *pol, - const struct effect_descriptor_s *desc, - audio_io_handle_t output, - uint32_t strategy, - audio_session_t session, - int id); - - int (*unregister_effect)(struct audio_policy *pol, int id); - - int (*set_effect_enabled)(struct audio_policy *pol, int id, bool enabled); - - bool (*is_stream_active)(const struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t in_past_ms); - - bool (*is_stream_active_remotely)(const struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t in_past_ms); - - bool (*is_source_active)(const struct audio_policy *pol, - audio_source_t source); - - /* dump state */ - int (*dump)(const struct audio_policy *pol, int fd); - - /* check if offload is possible for given sample rate, bitrate, duration, ... */ - bool (*is_offload_supported)(const struct audio_policy *pol, - const audio_offload_info_t *info); -}; - - -struct audio_policy_service_ops { - /* - * Audio output Control functions - */ - - /* Opens an audio output with the requested parameters. - * - * The parameter values can indicate to use the default values in case the - * audio policy manager has no specific requirements for the output being - * opened. - * - * When the function returns, the parameter values reflect the actual - * values used by the audio hardware output stream. - * - * The audio policy manager can check if the proposed parameters are - * suitable or not and act accordingly. - */ - audio_io_handle_t (*open_output)(void *service, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask, - uint32_t *pLatencyMs, - audio_output_flags_t flags); - - /* creates a special output that is duplicated to the two outputs passed as - * arguments. The duplication is performed by - * a special mixer thread in the AudioFlinger. - */ - audio_io_handle_t (*open_duplicate_output)(void *service, - audio_io_handle_t output1, - audio_io_handle_t output2); - - /* closes the output stream */ - int (*close_output)(void *service, audio_io_handle_t output); - - /* suspends the output. - * - * When an output is suspended, the corresponding audio hardware output - * stream is placed in standby and the AudioTracks attached to the mixer - * thread are still processed but the output mix is discarded. - */ - int (*suspend_output)(void *service, audio_io_handle_t output); - - /* restores a suspended output. */ - int (*restore_output)(void *service, audio_io_handle_t output); - - /* */ - /* Audio input Control functions */ - /* */ - - /* opens an audio input - * deprecated - new implementations should use open_input_on_module, - * and the acoustics parameter is ignored - */ - audio_io_handle_t (*open_input)(void *service, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask, - audio_in_acoustics_t acoustics); - - /* closes an audio input */ - int (*close_input)(void *service, audio_io_handle_t input); - - /* */ - /* misc control functions */ - /* */ - - /* set a stream volume for a particular output. - * - * For the same user setting, a given stream type can have different - * volumes for each output (destination device) it is attached to. - */ - int (*set_stream_volume)(void *service, - audio_stream_type_t stream, - float volume, - audio_io_handle_t output, - int delay_ms); - - /* invalidate a stream type, causing a reroute to an unspecified new output */ - int (*invalidate_stream)(void *service, - audio_stream_type_t stream); - - /* function enabling to send proprietary informations directly from audio - * policy manager to audio hardware interface. */ - void (*set_parameters)(void *service, - audio_io_handle_t io_handle, - const char *kv_pairs, - int delay_ms); - - /* function enabling to receive proprietary informations directly from - * audio hardware interface to audio policy manager. - * - * Returns a pointer to a heap allocated string. The caller is responsible - * for freeing the memory for it using free(). - */ - - char * (*get_parameters)(void *service, audio_io_handle_t io_handle, - const char *keys); - - /* request the playback of a tone on the specified stream. - * used for instance to replace notification sounds when playing over a - * telephony device during a phone call. - */ - int (*start_tone)(void *service, - audio_policy_tone_t tone, - audio_stream_type_t stream); - - int (*stop_tone)(void *service); - - /* set down link audio volume. */ - int (*set_voice_volume)(void *service, - float volume, - int delay_ms); - - /* move effect to the specified output */ - int (*move_effects)(void *service, - audio_session_t session, - audio_io_handle_t src_output, - audio_io_handle_t dst_output); - - /* loads an audio hw module. - * - * The module name passed is the base name of the HW module library, e.g "primary" or "a2dp". - * The function returns a handle on the module that will be used to specify a particular - * module when calling open_output_on_module() or open_input_on_module() - */ - audio_module_handle_t (*load_hw_module)(void *service, - const char *name); - - /* Opens an audio output on a particular HW module. - * - * Same as open_output() but specifying a specific HW module on which the output must be opened. - */ - audio_io_handle_t (*open_output_on_module)(void *service, - audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask, - uint32_t *pLatencyMs, - audio_output_flags_t flags, - const audio_offload_info_t *offloadInfo); - - /* Opens an audio input on a particular HW module. - * - * Same as open_input() but specifying a specific HW module on which the input must be opened. - * Also removed deprecated acoustics parameter - */ - audio_io_handle_t (*open_input_on_module)(void *service, - audio_module_handle_t module, - audio_devices_t *pDevices, - uint32_t *pSamplingRate, - audio_format_t *pFormat, - audio_channel_mask_t *pChannelMask); - -}; - -/**********************************************************************/ - -/** - * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM - * and the fields of this data structure must begin with hw_module_t - * followed by module specific information. - */ -typedef struct audio_policy_module { - struct hw_module_t common; -} audio_policy_module_t; - -struct audio_policy_device { - /** - * Common methods of the audio policy device. This *must* be the first member of - * audio_policy_device as users of this structure will cast a hw_device_t to - * audio_policy_device pointer in contexts where it's known the hw_device_t references an - * audio_policy_device. - */ - struct hw_device_t common; - - int (*create_audio_policy)(const struct audio_policy_device *device, - struct audio_policy_service_ops *aps_ops, - void *service, - struct audio_policy **ap); - - int (*destroy_audio_policy)(const struct audio_policy_device *device, - struct audio_policy *ap); -}; - -/** convenience API for opening and closing a supported device */ - -static inline int audio_policy_dev_open(const hw_module_t* module, - struct audio_policy_device** device) -{ - return module->methods->open(module, AUDIO_POLICY_INTERFACE, - (hw_device_t**)device); -} - -static inline int audio_policy_dev_close(struct audio_policy_device* device) -{ - return device->common.close(&device->common); -} - - -__END_DECLS - -#endif // ANDROID_AUDIO_POLICY_INTERFACE_H diff --git a/modules/audio/Android.bp b/modules/audio/Android.bp index a7467c29..7929c66c 100644 --- a/modules/audio/Android.bp +++ b/modules/audio/Android.bp @@ -23,7 +23,10 @@ cc_library_shared { relative_install_path: "hw", proprietary: true, srcs: ["audio_hw.c"], - header_libs: ["libhardware_headers"], + header_libs: [ + "libhardware_headers", + "android.hardware.audio.common.legacy@2.0", + ], shared_libs: [ "liblog", ], @@ -41,21 +44,10 @@ cc_library_shared { relative_install_path: "hw", proprietary: true, srcs: ["audio_hw.c"], - header_libs: ["libhardware_headers"], - shared_libs: [ - "liblog", - ], - cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"], -} - -// The stub audio policy HAL module that can be used as a skeleton for -// new implementations. -cc_library_shared { - name: "audio_policy.stub", - relative_install_path: "hw", - proprietary: true, - srcs: ["audio_policy.c"], - header_libs: ["libhardware_headers"], + header_libs: [ + "libhardware_headers", + "android.hardware.audio.common.legacy@2.0", + ], shared_libs: [ "liblog", ], diff --git a/modules/audio/audio_policy.c b/modules/audio/audio_policy.c deleted file mode 100644 index 4f9cd5a5..00000000 --- a/modules/audio/audio_policy.c +++ /dev/null @@ -1,350 +0,0 @@ -/* - * Copyright (C) 2011 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#define LOG_TAG "audio_policy_default" -//#define LOG_NDEBUG 0 - -#include -#include -#include -#include - -#include -#include -#include -#include - -struct default_ap_module { - struct audio_policy_module module; -}; - -struct default_ap_device { - struct audio_policy_device device; -}; - -struct default_audio_policy { - struct audio_policy policy; - - struct audio_policy_service_ops *aps_ops; - void *service; -}; - -static int ap_set_device_connection_state(struct audio_policy *pol, - audio_devices_t device, - audio_policy_dev_state_t state, - const char *device_address) -{ - return -ENOSYS; -} - -static audio_policy_dev_state_t ap_get_device_connection_state( - const struct audio_policy *pol, - audio_devices_t device, - const char *device_address) -{ - return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; -} - -static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state) -{ -} - -// deprecated, never called -static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, - uint32_t mask) -{ -} - -static void ap_set_force_use(struct audio_policy *pol, - audio_policy_force_use_t usage, - audio_policy_forced_cfg_t config) -{ -} - - /* retreive current device category forced for a given usage */ -static audio_policy_forced_cfg_t ap_get_force_use( - const struct audio_policy *pol, - audio_policy_force_use_t usage) -{ - return AUDIO_POLICY_FORCE_NONE; -} - -/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE - * can still be muted. */ -static void ap_set_can_mute_enforced_audible(struct audio_policy *pol, - bool can_mute) -{ -} - -static int ap_init_check(const struct audio_policy *pol) -{ - return 0; -} - -static audio_io_handle_t ap_get_output(struct audio_policy *pol, - audio_stream_type_t stream, - uint32_t sampling_rate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_output_flags_t flags, - const audio_offload_info_t *info) -{ - return 0; -} - -static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output, - audio_stream_type_t stream, int session) -{ - return -ENOSYS; -} - -static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output, - audio_stream_type_t stream, int session) -{ - return -ENOSYS; -} - -static void ap_release_output(struct audio_policy *pol, - audio_io_handle_t output) -{ -} - -static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource, - uint32_t sampling_rate, - audio_format_t format, - audio_channel_mask_t channelMask, - audio_in_acoustics_t acoustics) -{ - return 0; -} - -static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input) -{ - return -ENOSYS; -} - -static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input) -{ - return -ENOSYS; -} - -static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input) -{ -} - -static void ap_init_stream_volume(struct audio_policy *pol, - audio_stream_type_t stream, int index_min, - int index_max) -{ -} - -static int ap_set_stream_volume_index(struct audio_policy *pol, - audio_stream_type_t stream, - int index) -{ - return -ENOSYS; -} - -static int ap_get_stream_volume_index(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index) -{ - return -ENOSYS; -} - -static int ap_set_stream_volume_index_for_device(struct audio_policy *pol, - audio_stream_type_t stream, - int index, - audio_devices_t device) -{ - return -ENOSYS; -} - -static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol, - audio_stream_type_t stream, - int *index, - audio_devices_t device) -{ - return -ENOSYS; -} - -static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, - audio_stream_type_t stream) -{ - return 0; -} - -static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol, - audio_stream_type_t stream) -{ - return 0; -} - -static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, - const struct effect_descriptor_s *desc) -{ - return 0; -} - -static int ap_register_effect(struct audio_policy *pol, - const struct effect_descriptor_s *desc, - audio_io_handle_t output, - uint32_t strategy, - int session, - int id) -{ - return -ENOSYS; -} - -static int ap_unregister_effect(struct audio_policy *pol, int id) -{ - return -ENOSYS; -} - -static int ap_set_effect_enabled(struct audio_policy *pol, int id, bool enabled) -{ - return -ENOSYS; -} - -static bool ap_is_stream_active(const struct audio_policy *pol, audio_stream_type_t stream, - uint32_t in_past_ms) -{ - return false; -} - -static int ap_dump(const struct audio_policy *pol, int fd) -{ - return -ENOSYS; -} - -static bool ap_is_offload_supported(const struct audio_policy *pol, - const audio_offload_info_t *info) -{ - return false; -} - -static int create_default_ap(const struct audio_policy_device *device, - struct audio_policy_service_ops *aps_ops, - void *service, - struct audio_policy **ap) -{ - struct default_audio_policy *dap; - - *ap = NULL; - - if (!service || !aps_ops) - return -EINVAL; - - dap = (struct default_audio_policy *)calloc(1, sizeof(*dap)); - if (!dap) - return -ENOMEM; - - dap->policy.set_device_connection_state = ap_set_device_connection_state; - dap->policy.get_device_connection_state = ap_get_device_connection_state; - dap->policy.set_phone_state = ap_set_phone_state; - dap->policy.set_ringer_mode = ap_set_ringer_mode; - dap->policy.set_force_use = ap_set_force_use; - dap->policy.get_force_use = ap_get_force_use; - dap->policy.set_can_mute_enforced_audible = - ap_set_can_mute_enforced_audible; - dap->policy.init_check = ap_init_check; - dap->policy.get_output = ap_get_output; - dap->policy.start_output = ap_start_output; - dap->policy.stop_output = ap_stop_output; - dap->policy.release_output = ap_release_output; - dap->policy.get_input = ap_get_input; - dap->policy.start_input = ap_start_input; - dap->policy.stop_input = ap_stop_input; - dap->policy.release_input = ap_release_input; - dap->policy.init_stream_volume = ap_init_stream_volume; - dap->policy.set_stream_volume_index = ap_set_stream_volume_index; - dap->policy.get_stream_volume_index = ap_get_stream_volume_index; - dap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device; - dap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device; - dap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; - dap->policy.get_devices_for_stream = ap_get_devices_for_stream; - dap->policy.get_output_for_effect = ap_get_output_for_effect; - dap->policy.register_effect = ap_register_effect; - dap->policy.unregister_effect = ap_unregister_effect; - dap->policy.set_effect_enabled = ap_set_effect_enabled; - dap->policy.is_stream_active = ap_is_stream_active; - dap->policy.dump = ap_dump; - - dap->policy.is_offload_supported = ap_is_offload_supported; - - dap->service = service; - dap->aps_ops = aps_ops; - - *ap = &dap->policy; - return 0; -} - -static int destroy_default_ap(const struct audio_policy_device *ap_dev, - struct audio_policy *ap) -{ - free(ap); - return 0; -} - -static int default_ap_dev_close(hw_device_t* device) -{ - free(device); - return 0; -} - -static int default_ap_dev_open(const hw_module_t* module, const char* name, - hw_device_t** device) -{ - struct default_ap_device *dev; - - *device = NULL; - - if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0) - return -EINVAL; - - dev = (struct default_ap_device *)calloc(1, sizeof(*dev)); - if (!dev) - return -ENOMEM; - - dev->device.common.tag = HARDWARE_DEVICE_TAG; - dev->device.common.version = 0; - dev->device.common.module = (hw_module_t *)module; - dev->device.common.close = default_ap_dev_close; - dev->device.create_audio_policy = create_default_ap; - dev->device.destroy_audio_policy = destroy_default_ap; - - *device = &dev->device.common; - - return 0; -} - -static struct hw_module_methods_t default_ap_module_methods = { - .open = default_ap_dev_open, -}; - -struct default_ap_module HAL_MODULE_INFO_SYM = { - .module = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .version_major = 1, - .version_minor = 0, - .id = AUDIO_POLICY_HARDWARE_MODULE_ID, - .name = "Default audio policy HAL", - .author = "The Android Open Source Project", - .methods = &default_ap_module_methods, - }, - }, -}; diff --git a/modules/audio_remote_submix/Android.bp b/modules/audio_remote_submix/Android.bp index c7d018c0..578949ed 100644 --- a/modules/audio_remote_submix/Android.bp +++ b/modules/audio_remote_submix/Android.bp @@ -17,16 +17,15 @@ cc_library_shared { relative_install_path: "hw", vendor: true, srcs: ["audio_hw.cpp"], - include_dirs: [ - "system/media/audio_utils/include", - ], + shared_libs: [ "liblog", "libcutils", "libutils", - "libnbaio_mono", + "libnbaio_mono@2.0", + "libaudioutils", ], - static_libs: ["libmedia_helper"], + static_libs: ["libmedia_helper@2.0"], cflags: ["-Wno-unused-parameter"], diff --git a/modules/usbaudio/Android.bp b/modules/usbaudio/Android.bp index c7d403f5..ecc74fbd 100644 --- a/modules/usbaudio/Android.bp +++ b/modules/usbaudio/Android.bp @@ -25,5 +25,7 @@ cc_library_shared { "libalsautils", ], cflags: ["-Wno-unused-parameter"], - header_libs: ["libhardware_headers"], + header_libs: [ + "android.hardware.audio.common.legacy@2.0", + ], } From 34a97f80e20efdee20f469b9b001cfdad23826a0 Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 22 Jan 2018 13:34:30 -0800 Subject: [PATCH 23/50] Add camera-specific OWNER Test: Builds Change-Id: I86a08e487745640858028dd24f01e8f2c35aebca --- OWNERS | 1 + 1 file changed, 1 insertion(+) diff --git a/OWNERS b/OWNERS index 0c22ffda..da2454a9 100644 --- a/OWNERS +++ b/OWNERS @@ -4,3 +4,4 @@ jpawlowski@google.com malchev@google.com smoreland@google.com swillden@google.com +per-file include/hardware/camera*=etalvala@google.com From cc1aa87b19b236076fd56f0435d0731b9aacd00f Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 22 Jan 2018 13:30:52 -0800 Subject: [PATCH 24/50] Camera3: Add new MOTION_TRACKING template enums Bug: 70565622 Bug: 63629224 Test: Builds, CTS passes Change-Id: I927776d042b74013cf24c342b107a5aee1ad26a2 --- include/hardware/camera3.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index 53e8d7b7..ad088835 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -182,6 +182,8 @@ * - Add physical camera id and settings field in camera3_capture_request, so that * for a logical multi camera, the application has the option to specify individual * settings for a particular physical device. + * + * - Add request templates MOTION_TRACKING_PREVIEW and MOTION_TRACKING_BEST */ /** @@ -2180,6 +2182,10 @@ typedef enum camera3_request_template { */ CAMERA3_TEMPLATE_MANUAL = 6, + // Added in 3.5 + CAMERA3_TEMPLATE_MOTION_TRACKING_PREVIEW = 7, + CAMERA3_TEMPLATE_MOTION_TRACKING_BEST = 8, + /* Total number of templates */ CAMERA3_TEMPLATE_COUNT, From c6ec9486d80a58a2f9fdaff2a2660dec125aac28 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Wed, 24 Jan 2018 06:04:27 +0000 Subject: [PATCH 25/50] Revert "Audio V4: Split system and vendor Audio.h" This reverts commit fc9e212f018ce41430ec8dcebc3cae3c346474bb. Reason for revert: Breaks multiple devices Change-Id: I816671fd92246f85c97d00819858a74e36e2929d --- Android.bp | 2 + include/hardware/audio.h | 745 +++++++++++++++++++++++++ include/hardware/audio_alsaops.h | 103 ++++ include/hardware/audio_effect.h | 310 ++++++++++ include/hardware/audio_policy.h | 457 +++++++++++++++ modules/audio/Android.bp | 24 +- modules/audio/audio_policy.c | 350 ++++++++++++ modules/audio_remote_submix/Android.bp | 9 +- modules/usbaudio/Android.bp | 4 +- 9 files changed, 1989 insertions(+), 15 deletions(-) create mode 100644 include/hardware/audio.h create mode 100644 include/hardware/audio_alsaops.h create mode 100644 include/hardware/audio_effect.h create mode 100644 include/hardware/audio_policy.h create mode 100644 modules/audio/audio_policy.c diff --git a/Android.bp b/Android.bp index fd138b01..4766b71d 100644 --- a/Android.bp +++ b/Android.bp @@ -3,11 +3,13 @@ cc_library_headers { name: "libhardware_headers", header_libs: [ + "libaudio_system_headers", "libsystem_headers", "libcutils_headers", "libbluetooth-types-header", ], export_header_lib_headers: [ + "libaudio_system_headers", "libsystem_headers", "libcutils_headers", "libbluetooth-types-header", diff --git a/include/hardware/audio.h b/include/hardware/audio.h new file mode 100644 index 00000000..2d6eb309 --- /dev/null +++ b/include/hardware/audio.h @@ -0,0 +1,745 @@ +/* + * Copyright (C) 2011 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_AUDIO_HAL_INTERFACE_H +#define ANDROID_AUDIO_HAL_INTERFACE_H + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define AUDIO_HARDWARE_MODULE_ID "audio" + +/** + * Name of the audio devices to open + */ +#define AUDIO_HARDWARE_INTERFACE "audio_hw_if" + + +/* Use version 0.1 to be compatible with first generation of audio hw module with version_major + * hardcoded to 1. No audio module API change. + */ +#define AUDIO_MODULE_API_VERSION_0_1 HARDWARE_MODULE_API_VERSION(0, 1) +#define AUDIO_MODULE_API_VERSION_CURRENT AUDIO_MODULE_API_VERSION_0_1 + +/* First generation of audio devices had version hardcoded to 0. all devices with versions < 1.0 + * will be considered of first generation API. + */ +#define AUDIO_DEVICE_API_VERSION_0_0 HARDWARE_DEVICE_API_VERSION(0, 0) +#define AUDIO_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION(1, 0) +#define AUDIO_DEVICE_API_VERSION_2_0 HARDWARE_DEVICE_API_VERSION(2, 0) +#define AUDIO_DEVICE_API_VERSION_3_0 HARDWARE_DEVICE_API_VERSION(3, 0) +#define AUDIO_DEVICE_API_VERSION_CURRENT AUDIO_DEVICE_API_VERSION_3_0 +/* Minimal audio HAL version supported by the audio framework */ +#define AUDIO_DEVICE_API_VERSION_MIN AUDIO_DEVICE_API_VERSION_2_0 + +/**************************************/ + +/** + * standard audio parameters that the HAL may need to handle + */ + +/** + * audio device parameters + */ + +/* TTY mode selection */ +#define AUDIO_PARAMETER_KEY_TTY_MODE "tty_mode" +#define AUDIO_PARAMETER_VALUE_TTY_OFF "tty_off" +#define AUDIO_PARAMETER_VALUE_TTY_VCO "tty_vco" +#define AUDIO_PARAMETER_VALUE_TTY_HCO "tty_hco" +#define AUDIO_PARAMETER_VALUE_TTY_FULL "tty_full" + +/* Hearing Aid Compatibility - Telecoil (HAC-T) mode on/off */ +#define AUDIO_PARAMETER_KEY_HAC "HACSetting" +#define AUDIO_PARAMETER_VALUE_HAC_ON "ON" +#define AUDIO_PARAMETER_VALUE_HAC_OFF "OFF" + +/* A2DP sink address set by framework */ +#define AUDIO_PARAMETER_A2DP_SINK_ADDRESS "a2dp_sink_address" + +/* A2DP source address set by framework */ +#define AUDIO_PARAMETER_A2DP_SOURCE_ADDRESS "a2dp_source_address" + +/* Bluetooth SCO wideband */ +#define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs" + +/** + * audio stream parameters + */ + +/* Enable AANC */ +#define AUDIO_PARAMETER_KEY_AANC "aanc_enabled" + +/**************************************/ + +/* common audio stream parameters and operations */ +struct audio_stream { + + /** + * Return the sampling rate in Hz - eg. 44100. + */ + uint32_t (*get_sample_rate)(const struct audio_stream *stream); + + /* currently unused - use set_parameters with key + * AUDIO_PARAMETER_STREAM_SAMPLING_RATE + */ + int (*set_sample_rate)(struct audio_stream *stream, uint32_t rate); + + /** + * Return size of input/output buffer in bytes for this stream - eg. 4800. + * It should be a multiple of the frame size. See also get_input_buffer_size. + */ + size_t (*get_buffer_size)(const struct audio_stream *stream); + + /** + * Return the channel mask - + * e.g. AUDIO_CHANNEL_OUT_STEREO or AUDIO_CHANNEL_IN_STEREO + */ + audio_channel_mask_t (*get_channels)(const struct audio_stream *stream); + + /** + * Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT + */ + audio_format_t (*get_format)(const struct audio_stream *stream); + + /* currently unused - use set_parameters with key + * AUDIO_PARAMETER_STREAM_FORMAT + */ + int (*set_format)(struct audio_stream *stream, audio_format_t format); + + /** + * Put the audio hardware input/output into standby mode. + * Driver should exit from standby mode at the next I/O operation. + * Returns 0 on success and <0 on failure. + */ + int (*standby)(struct audio_stream *stream); + + /** dump the state of the audio input/output device */ + int (*dump)(const struct audio_stream *stream, int fd); + + /** Return the set of device(s) which this stream is connected to */ + audio_devices_t (*get_device)(const struct audio_stream *stream); + + /** + * Currently unused - set_device() corresponds to set_parameters() with key + * AUDIO_PARAMETER_STREAM_ROUTING for both input and output. + * AUDIO_PARAMETER_STREAM_INPUT_SOURCE is an additional information used by + * input streams only. + */ + int (*set_device)(struct audio_stream *stream, audio_devices_t device); + + /** + * set/get audio stream parameters. The function accepts a list of + * parameter key value pairs in the form: key1=value1;key2=value2;... + * + * Some keys are reserved for standard parameters (See AudioParameter class) + * + * If the implementation does not accept a parameter change while + * the output is active but the parameter is acceptable otherwise, it must + * return -ENOSYS. + * + * The audio flinger will put the stream in standby and then change the + * parameter value. + */ + int (*set_parameters)(struct audio_stream *stream, const char *kv_pairs); + + /* + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + char * (*get_parameters)(const struct audio_stream *stream, + const char *keys); + int (*add_audio_effect)(const struct audio_stream *stream, + effect_handle_t effect); + int (*remove_audio_effect)(const struct audio_stream *stream, + effect_handle_t effect); +}; +typedef struct audio_stream audio_stream_t; + +/* 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_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); + +/* type of drain requested to audio_stream_out->drain(). Mutually exclusive */ +typedef enum { + AUDIO_DRAIN_ALL, /* drain() returns when all data has been played */ + AUDIO_DRAIN_EARLY_NOTIFY /* drain() returns a short time before all data + from the current track has been played to + give time for gapless track switch */ +} audio_drain_type_t; + +/** + * audio_stream_out is the abstraction interface for the audio output hardware. + * + * It provides information about various properties of the audio output + * hardware driver. + */ + +struct audio_stream_out { + /** + * Common methods of the audio stream out. This *must* be the first member of audio_stream_out + * as users of this structure will cast a audio_stream to audio_stream_out pointer in contexts + * where it's known the audio_stream references an audio_stream_out. + */ + struct audio_stream common; + + /** + * Return the audio hardware driver estimated latency in milliseconds. + */ + uint32_t (*get_latency)(const struct audio_stream_out *stream); + + /** + * Use this method in situations where audio mixing is done in the + * hardware. This method serves as a direct interface with hardware, + * allowing you to directly set the volume as apposed to via the framework. + * This method might produce multiple PCM outputs or hardware accelerated + * codecs, such as MP3 or AAC. + */ + int (*set_volume)(struct audio_stream_out *stream, float left, float right); + + /** + * Write audio buffer to driver. Returns number of bytes written, or a + * negative status_t. If at least one frame was written successfully prior to the error, + * it is suggested that the driver return that successful (short) byte count + * and then return an error in the subsequent call. + * + * If set_callback() has previously been called to enable non-blocking mode + * the write() is not allowed to block. It must write only the number of + * bytes that currently fit in the driver/hardware buffer and then return + * this byte count. If this is less than the requested write size the + * callback function must be called when more space is available in the + * driver/hardware buffer. + */ + ssize_t (*write)(struct audio_stream_out *stream, const void* buffer, + size_t bytes); + + /* return the number of audio frames written by the audio dsp to DAC since + * the output has exited standby + */ + int (*get_render_position)(const struct audio_stream_out *stream, + uint32_t *dsp_frames); + + /** + * get the local time at which the next write to the audio driver will be presented. + * The units are microseconds, where the epoch is decided by the local audio HAL. + */ + int (*get_next_write_timestamp)(const struct audio_stream_out *stream, + int64_t *timestamp); + + /** + * set the callback function for notifying completion of non-blocking + * write and drain. + * Calling this function implies that all future write() and drain() + * must be non-blocking and use the callback to signal completion. + */ + int (*set_callback)(struct audio_stream_out *stream, + stream_callback_t callback, void *cookie); + + /** + * Notifies to the audio driver to stop playback however the queued buffers are + * retained by the hardware. Useful for implementing pause/resume. Empty implementation + * if not supported however should be implemented for hardware with non-trivial + * latency. In the pause state audio hardware could still be using power. User may + * consider calling suspend after a timeout. + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*pause)(struct audio_stream_out* stream); + + /** + * Notifies to the audio driver to resume playback following a pause. + * Returns error if called without matching pause. + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*resume)(struct audio_stream_out* stream); + + /** + * Requests notification when data buffered by the driver/hardware has + * been played. If set_callback() has previously been called to enable + * non-blocking mode, the drain() must not block, instead it should return + * quickly and completion of the drain is notified through the callback. + * If set_callback() has not been called, the drain() must block until + * completion. + * If type==AUDIO_DRAIN_ALL, the drain completes when all previously written + * data has been played. + * If type==AUDIO_DRAIN_EARLY_NOTIFY, the drain completes shortly before all + * data for the current track has played to allow time for the framework + * to perform a gapless track switch. + * + * Drain must return immediately on stop() and flush() call + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*drain)(struct audio_stream_out* stream, audio_drain_type_t type ); + + /** + * Notifies to the audio driver to flush the queued data. Stream must already + * be paused before calling flush(). + * + * Implementation of this function is mandatory for offloaded playback. + */ + int (*flush)(struct audio_stream_out* stream); + + /** + * Return a recent count of the number of audio frames presented to an external observer. + * This excludes frames which have been written but are still in the pipeline. + * The count is not reset to zero when output enters standby. + * Also returns the value of CLOCK_MONOTONIC as of this presentation count. + * The returned count is expected to be 'recent', + * but does not need to be the most recent possible value. + * However, the associated time should correspond to whatever count is returned. + * Example: assume that N+M frames have been presented, where M is a 'small' number. + * Then it is permissible to return N instead of N+M, + * and the timestamp should correspond to N rather than N+M. + * The terms 'recent' and 'small' are not defined. + * They reflect the quality of the implementation. + * + * 3.0 and higher only. + */ + int (*get_presentation_position)(const struct audio_stream_out *stream, + uint64_t *frames, struct timespec *timestamp); + + /** + * Called by the framework to start a stream operating in mmap mode. + * create_mmap_buffer must be called before calling start() + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \return 0 in case of success. + * -ENOSYS if called out of sequence or on non mmap stream + */ + int (*start)(const struct audio_stream_out* stream); + + /** + * Called by the framework to stop a stream operating in mmap mode. + * Must be called after start() + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \return 0 in case of success. + * -ENOSYS if called out of sequence or on non mmap stream + */ + int (*stop)(const struct audio_stream_out* stream); + + /** + * Called by the framework to retrieve information on the mmap buffer used for audio + * samples transfer. + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \param[in] min_size_frames minimum buffer size requested. The actual buffer + * size returned in struct audio_mmap_buffer_info can be larger. + * \param[out] info address at which the mmap buffer information should be returned. + * + * \return 0 if the buffer was allocated. + * -ENODEV in case of initialization error + * -EINVAL if the requested buffer size is too large + * -ENOSYS if called out of sequence (e.g. buffer already allocated) + */ + int (*create_mmap_buffer)(const struct audio_stream_out *stream, + int32_t min_size_frames, + struct audio_mmap_buffer_info *info); + + /** + * Called by the framework to read current read/write position in the mmap buffer + * with associated time stamp. + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \param[out] position address at which the mmap read/write position should be returned. + * + * \return 0 if the position is successfully returned. + * -ENODATA if the position cannot be retrieved + * -ENOSYS if called before create_mmap_buffer() + */ + int (*get_mmap_position)(const struct audio_stream_out *stream, + struct audio_mmap_position *position); +}; +typedef struct audio_stream_out audio_stream_out_t; + +struct audio_stream_in { + /** + * Common methods of the audio stream in. This *must* be the first member of audio_stream_in + * as users of this structure will cast a audio_stream to audio_stream_in pointer in contexts + * where it's known the audio_stream references an audio_stream_in. + */ + struct audio_stream common; + + /** set the input gain for the audio driver. This method is for + * for future use */ + int (*set_gain)(struct audio_stream_in *stream, float gain); + + /** Read audio buffer in from audio driver. Returns number of bytes read, or a + * negative status_t. If at least one frame was read prior to the error, + * read should return that byte count and then return an error in the subsequent call. + */ + ssize_t (*read)(struct audio_stream_in *stream, void* buffer, + size_t bytes); + + /** + * Return the amount of input frames lost in the audio driver since the + * last call of this function. + * Audio driver is expected to reset the value to 0 and restart counting + * upon returning the current value by this function call. + * Such loss typically occurs when the user space process is blocked + * longer than the capacity of audio driver buffers. + * + * Unit: the number of input audio frames + */ + uint32_t (*get_input_frames_lost)(struct audio_stream_in *stream); + + /** + * Return a recent count of the number of audio frames received and + * the clock time associated with that frame count. + * + * frames is the total frame count received. This should be as early in + * the capture pipeline as possible. In general, + * frames should be non-negative and should not go "backwards". + * + * time is the clock MONOTONIC time when frames was measured. In general, + * time should be a positive quantity and should not go "backwards". + * + * The status returned is 0 on success, -ENOSYS if the device is not + * ready/available, or -EINVAL if the arguments are null or otherwise invalid. + */ + int (*get_capture_position)(const struct audio_stream_in *stream, + int64_t *frames, int64_t *time); + + /** + * Called by the framework to start a stream operating in mmap mode. + * create_mmap_buffer must be called before calling start() + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \return 0 in case off success. + * -ENOSYS if called out of sequence or on non mmap stream + */ + int (*start)(const struct audio_stream_in* stream); + + /** + * Called by the framework to stop a stream operating in mmap mode. + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \return 0 in case of success. + * -ENOSYS if called out of sequence or on non mmap stream + */ + int (*stop)(const struct audio_stream_in* stream); + + /** + * Called by the framework to retrieve information on the mmap buffer used for audio + * samples transfer. + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \param[in] min_size_frames minimum buffer size requested. The actual buffer + * size returned in struct audio_mmap_buffer_info can be larger. + * \param[out] info address at which the mmap buffer information should be returned. + * + * \return 0 if the buffer was allocated. + * -ENODEV in case of initialization error + * -EINVAL if the requested buffer size is too large + * -ENOSYS if called out of sequence (e.g. buffer already allocated) + */ + int (*create_mmap_buffer)(const struct audio_stream_in *stream, + int32_t min_size_frames, + struct audio_mmap_buffer_info *info); + + /** + * Called by the framework to read current read/write position in the mmap buffer + * with associated time stamp. + * + * \note Function only implemented by streams operating in mmap mode. + * + * \param[in] stream the stream object. + * \param[out] position address at which the mmap read/write position should be returned. + * + * \return 0 if the position is successfully returned. + * -ENODATA if the position cannot be retreived + * -ENOSYS if called before mmap_read_position() + */ + int (*get_mmap_position)(const struct audio_stream_in *stream, + struct audio_mmap_position *position); +}; +typedef struct audio_stream_in audio_stream_in_t; + +/** + * return the frame size (number of bytes per sample). + * + * Deprecated: use audio_stream_out_frame_size() or audio_stream_in_frame_size() instead. + */ +__attribute__((__deprecated__)) +static inline size_t audio_stream_frame_size(const struct audio_stream *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->get_format(s); + + if (audio_has_proportional_frames(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return popcount(s->get_channels(s)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/** + * return the frame size (number of bytes per sample) of an output stream. + */ +static inline size_t audio_stream_out_frame_size(const struct audio_stream_out *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->common.get_format(&s->common); + + if (audio_has_proportional_frames(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return audio_channel_count_from_out_mask(s->common.get_channels(&s->common)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/** + * return the frame size (number of bytes per sample) of an input stream. + */ +static inline size_t audio_stream_in_frame_size(const struct audio_stream_in *s) +{ + size_t chan_samp_sz; + audio_format_t format = s->common.get_format(&s->common); + + if (audio_has_proportional_frames(format)) { + chan_samp_sz = audio_bytes_per_sample(format); + return audio_channel_count_from_in_mask(s->common.get_channels(&s->common)) * chan_samp_sz; + } + + return sizeof(int8_t); +} + +/**********************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +struct audio_module { + struct hw_module_t common; +}; + +struct audio_hw_device { + /** + * Common methods of the audio device. This *must* be the first member of audio_hw_device + * as users of this structure will cast a hw_device_t to audio_hw_device pointer in contexts + * where it's known the hw_device_t references an audio_hw_device. + */ + struct hw_device_t common; + + /** + * used by audio flinger to enumerate what devices are supported by + * each audio_hw_device implementation. + * + * Return value is a bitmask of 1 or more values of audio_devices_t + * + * NOTE: audio HAL implementations starting with + * AUDIO_DEVICE_API_VERSION_2_0 do not implement this function. + * All supported devices should be listed in audio_policy.conf + * file and the audio policy manager must choose the appropriate + * audio module based on information in this file. + */ + uint32_t (*get_supported_devices)(const struct audio_hw_device *dev); + + /** + * check to see if the audio hardware interface has been initialized. + * returns 0 on success, -ENODEV on failure. + */ + int (*init_check)(const struct audio_hw_device *dev); + + /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */ + int (*set_voice_volume)(struct audio_hw_device *dev, float volume); + + /** + * set the audio volume for all audio activities other than voice call. + * Range between 0.0 and 1.0. If any value other than 0 is returned, + * the software mixer will emulate this capability. + */ + int (*set_master_volume)(struct audio_hw_device *dev, float volume); + + /** + * Get the current master volume value for the HAL, if the HAL supports + * master volume control. AudioFlinger will query this value from the + * primary audio HAL when the service starts and use the value for setting + * the initial master volume across all HALs. HALs which do not support + * this method may leave it set to NULL. + */ + int (*get_master_volume)(struct audio_hw_device *dev, float *volume); + + /** + * set_mode is called when the audio mode changes. AUDIO_MODE_NORMAL mode + * is for standard audio playback, AUDIO_MODE_RINGTONE when a ringtone is + * playing, and AUDIO_MODE_IN_CALL when a call is in progress. + */ + int (*set_mode)(struct audio_hw_device *dev, audio_mode_t mode); + + /* mic mute */ + int (*set_mic_mute)(struct audio_hw_device *dev, bool state); + int (*get_mic_mute)(const struct audio_hw_device *dev, bool *state); + + /* set/get global audio parameters */ + int (*set_parameters)(struct audio_hw_device *dev, const char *kv_pairs); + + /* + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + char * (*get_parameters)(const struct audio_hw_device *dev, + const char *keys); + + /* Returns audio input buffer size according to parameters passed or + * 0 if one of the parameters is not supported. + * See also get_buffer_size which is for a particular stream. + */ + size_t (*get_input_buffer_size)(const struct audio_hw_device *dev, + const struct audio_config *config); + + /** This method creates and opens the audio hardware output stream. + * The "address" parameter qualifies the "devices" audio device type if needed. + * The format format depends on the device type: + * - Bluetooth devices use the MAC address of the device in the form "00:11:22:AA:BB:CC" + * - USB devices use the ALSA card and device numbers in the form "card=X;device=Y" + * - Other devices may use a number or any other string. + */ + + int (*open_output_stream)(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + audio_output_flags_t flags, + struct audio_config *config, + struct audio_stream_out **stream_out, + const char *address); + + void (*close_output_stream)(struct audio_hw_device *dev, + struct audio_stream_out* stream_out); + + /** This method creates and opens the audio hardware input stream */ + int (*open_input_stream)(struct audio_hw_device *dev, + audio_io_handle_t handle, + audio_devices_t devices, + struct audio_config *config, + struct audio_stream_in **stream_in, + audio_input_flags_t flags, + const char *address, + audio_source_t source); + + void (*close_input_stream)(struct audio_hw_device *dev, + struct audio_stream_in *stream_in); + + /** This method dumps the state of the audio hardware */ + int (*dump)(const struct audio_hw_device *dev, int fd); + + /** + * set the audio mute status for all audio activities. If any value other + * than 0 is returned, the software mixer will emulate this capability. + */ + int (*set_master_mute)(struct audio_hw_device *dev, bool mute); + + /** + * Get the current master mute status for the HAL, if the HAL supports + * master mute control. AudioFlinger will query this value from the primary + * audio HAL when the service starts and use the value for setting the + * initial master mute across all HALs. HALs which do not support this + * method may leave it set to NULL. + */ + int (*get_master_mute)(struct audio_hw_device *dev, bool *mute); + + /** + * Routing control + */ + + /* Creates an audio patch between several source and sink ports. + * The handle is allocated by the HAL and should be unique for this + * audio HAL module. */ + int (*create_audio_patch)(struct audio_hw_device *dev, + unsigned int num_sources, + const struct audio_port_config *sources, + unsigned int num_sinks, + const struct audio_port_config *sinks, + audio_patch_handle_t *handle); + + /* Release an audio patch */ + int (*release_audio_patch)(struct audio_hw_device *dev, + audio_patch_handle_t handle); + + /* Fills the list of supported attributes for a given audio port. + * As input, "port" contains the information (type, role, address etc...) + * needed by the HAL to identify the port. + * As output, "port" contains possible attributes (sampling rates, formats, + * channel masks, gain controllers...) for this port. + */ + int (*get_audio_port)(struct audio_hw_device *dev, + struct audio_port *port); + + /* Set audio port configuration */ + int (*set_audio_port_config)(struct audio_hw_device *dev, + const struct audio_port_config *config); + +}; +typedef struct audio_hw_device audio_hw_device_t; + +/** convenience API for opening and closing a supported device */ + +static inline int audio_hw_device_open(const struct hw_module_t* module, + struct audio_hw_device** device) +{ + return module->methods->open(module, AUDIO_HARDWARE_INTERFACE, + TO_HW_DEVICE_T_OPEN(device)); +} + +static inline int audio_hw_device_close(struct audio_hw_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_AUDIO_INTERFACE_H diff --git a/include/hardware/audio_alsaops.h b/include/hardware/audio_alsaops.h new file mode 100644 index 00000000..6a17a351 --- /dev/null +++ b/include/hardware/audio_alsaops.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2014 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. + */ + +/* This file contains shared utility functions to handle the tinyalsa + * implementation for Android internal audio, generally in the hardware layer. + * Some routines may log a fatal error on failure, as noted. + */ + +#ifndef ANDROID_AUDIO_ALSAOPS_H +#define ANDROID_AUDIO_ALSAOPS_H + +#include + +#include +#include + +__BEGIN_DECLS + +/* Converts audio_format to pcm_format. + * Parameters: + * format the audio_format_t to convert + * + * Logs a fatal error if format is not a valid convertible audio_format_t. + */ +static inline enum pcm_format pcm_format_from_audio_format(audio_format_t format) +{ + switch (format) { +#if HAVE_BIG_ENDIAN + case AUDIO_FORMAT_PCM_16_BIT: + return PCM_FORMAT_S16_BE; + case AUDIO_FORMAT_PCM_24_BIT_PACKED: + return PCM_FORMAT_S24_3BE; + case AUDIO_FORMAT_PCM_32_BIT: + return PCM_FORMAT_S32_BE; + case AUDIO_FORMAT_PCM_8_24_BIT: + return PCM_FORMAT_S24_BE; +#else + case AUDIO_FORMAT_PCM_16_BIT: + return PCM_FORMAT_S16_LE; + case AUDIO_FORMAT_PCM_24_BIT_PACKED: + return PCM_FORMAT_S24_3LE; + case AUDIO_FORMAT_PCM_32_BIT: + return PCM_FORMAT_S32_LE; + case AUDIO_FORMAT_PCM_8_24_BIT: + return PCM_FORMAT_S24_LE; +#endif + case AUDIO_FORMAT_PCM_FLOAT: /* there is no equivalent for float */ + default: + LOG_ALWAYS_FATAL("pcm_format_from_audio_format: invalid audio format %#x", format); + return 0; + } +} + +/* Converts pcm_format to audio_format. + * Parameters: + * format the pcm_format to convert + * + * Logs a fatal error if format is not a valid convertible pcm_format. + */ +static inline audio_format_t audio_format_from_pcm_format(enum pcm_format format) +{ + switch (format) { +#if HAVE_BIG_ENDIAN + case PCM_FORMAT_S16_BE: + return AUDIO_FORMAT_PCM_16_BIT; + case PCM_FORMAT_S24_3BE: + return AUDIO_FORMAT_PCM_24_BIT_PACKED; + case PCM_FORMAT_S24_BE: + return AUDIO_FORMAT_PCM_8_24_BIT; + case PCM_FORMAT_S32_BE: + return AUDIO_FORMAT_PCM_32_BIT; +#else + case PCM_FORMAT_S16_LE: + return AUDIO_FORMAT_PCM_16_BIT; + case PCM_FORMAT_S24_3LE: + return AUDIO_FORMAT_PCM_24_BIT_PACKED; + case PCM_FORMAT_S24_LE: + return AUDIO_FORMAT_PCM_8_24_BIT; + case PCM_FORMAT_S32_LE: + return AUDIO_FORMAT_PCM_32_BIT; +#endif + default: + LOG_ALWAYS_FATAL("audio_format_from_pcm_format: invalid pcm format %#x", format); + return 0; + } +} + +__END_DECLS + +#endif /* ANDROID_AUDIO_ALSAOPS_H */ diff --git a/include/hardware/audio_effect.h b/include/hardware/audio_effect.h new file mode 100644 index 00000000..3366e178 --- /dev/null +++ b/include/hardware/audio_effect.h @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2011 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_AUDIO_EFFECT_H +#define ANDROID_AUDIO_EFFECT_H + +#include +#include +#include +#include +#include + +#include + +#include + + +__BEGIN_DECLS + + +///////////////////////////////////////////////// +// Common Definitions +///////////////////////////////////////////////// + +#define EFFECT_MAKE_API_VERSION(M, m) (((M)<<16) | ((m) & 0xFFFF)) +#define EFFECT_API_VERSION_MAJOR(v) ((v)>>16) +#define EFFECT_API_VERSION_MINOR(v) ((m) & 0xFFFF) + + +///////////////////////////////////////////////// +// Effect control interface +///////////////////////////////////////////////// + +// Effect control interface version 2.0 +#define EFFECT_CONTROL_API_VERSION EFFECT_MAKE_API_VERSION(2,0) + +// Effect control interface structure: effect_interface_s +// The effect control interface is exposed by each effect engine implementation. It consists of +// a set of functions controlling the configuration, activation and process of the engine. +// The functions are grouped in a structure of type effect_interface_s. +// +// Effect control interface handle: effect_handle_t +// The effect_handle_t serves two purposes regarding the implementation of the effect engine: +// - 1 it is the address of a pointer to an effect_interface_s structure where the functions +// of the effect control API for a particular effect are located. +// - 2 it is the address of the context of a particular effect instance. +// A typical implementation in the effect library would define a structure as follows: +// struct effect_module_s { +// const struct effect_interface_s *itfe; +// effect_config_t config; +// effect_context_t context; +// } +// The implementation of EffectCreate() function would then allocate a structure of this +// type and return its address as effect_handle_t +typedef struct effect_interface_s **effect_handle_t; + +// Effect control interface definition +struct effect_interface_s { + //////////////////////////////////////////////////////////////////////////////// + // + // Function: process + // + // Description: Effect process function. Takes input samples as specified + // (count and location) in input buffer descriptor and output processed + // samples as specified in output buffer descriptor. If the buffer descriptor + // is not specified the function must use either the buffer or the + // buffer provider function installed by the EFFECT_CMD_SET_CONFIG command. + // The effect framework will call the process() function after the EFFECT_CMD_ENABLE + // command is received and until the EFFECT_CMD_DISABLE is received. When the engine + // receives the EFFECT_CMD_DISABLE command it should turn off the effect gracefully + // and when done indicate that it is OK to stop calling the process() function by + // returning the -ENODATA status. + // + // NOTE: the process() function implementation should be "real-time safe" that is + // it should not perform blocking calls: malloc/free, sleep, read/write/open/close, + // pthread_cond_wait/pthread_mutex_lock... + // + // Input: + // self: handle to the effect interface this function + // is called on. + // inBuffer: buffer descriptor indicating where to read samples to process. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. + // + // outBuffer: buffer descriptor indicating where to write processed samples. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG command. + // + // Output: + // returned value: 0 successful operation + // -ENODATA the engine has finished the disable phase and the framework + // can stop calling process() + // -EINVAL invalid interface handle or + // invalid input/output buffer description + //////////////////////////////////////////////////////////////////////////////// + int32_t (*process)(effect_handle_t self, + audio_buffer_t *inBuffer, + audio_buffer_t *outBuffer); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: command + // + // Description: Send a command and receive a response to/from effect engine. + // + // Input: + // self: handle to the effect interface this function + // is called on. + // cmdCode: command code: the command can be a standardized command defined in + // effect_command_e (see below) or a proprietary command. + // cmdSize: size of command in bytes + // pCmdData: pointer to command data + // pReplyData: pointer to reply data + // + // Input/Output: + // replySize: maximum size of reply data as input + // actual size of reply data as output + // + // Output: + // returned value: 0 successful operation + // -EINVAL invalid interface handle or + // invalid command/reply size or format according to + // command code + // The return code should be restricted to indicate problems related to this API + // specification. Status related to the execution of a particular command should be + // indicated as part of the reply field. + // + // *pReplyData updated with command response + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*command)(effect_handle_t self, + uint32_t cmdCode, + uint32_t cmdSize, + void *pCmdData, + uint32_t *replySize, + void *pReplyData); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: get_descriptor + // + // Description: Returns the effect descriptor + // + // Input: + // self: handle to the effect interface this function + // is called on. + // + // Input/Output: + // pDescriptor: address where to return the effect descriptor. + // + // Output: + // returned value: 0 successful operation. + // -EINVAL invalid interface handle or invalid pDescriptor + // *pDescriptor: updated with the effect descriptor. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*get_descriptor)(effect_handle_t self, + effect_descriptor_t *pDescriptor); + //////////////////////////////////////////////////////////////////////////////// + // + // Function: process_reverse + // + // Description: Process reverse stream function. This function is used to pass + // a reference stream to the effect engine. If the engine does not need a reference + // stream, this function pointer can be set to NULL. + // This function would typically implemented by an Echo Canceler. + // + // Input: + // self: handle to the effect interface this function + // is called on. + // inBuffer: buffer descriptor indicating where to read samples to process. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. + // + // outBuffer: buffer descriptor indicating where to write processed samples. + // If NULL, use the configuration passed by EFFECT_CMD_SET_CONFIG_REVERSE command. + // If the buffer and buffer provider in the configuration received by + // EFFECT_CMD_SET_CONFIG_REVERSE are also NULL, do not return modified reverse + // stream data + // + // Output: + // returned value: 0 successful operation + // -ENODATA the engine has finished the disable phase and the framework + // can stop calling process_reverse() + // -EINVAL invalid interface handle or + // invalid input/output buffer description + //////////////////////////////////////////////////////////////////////////////// + int32_t (*process_reverse)(effect_handle_t self, + audio_buffer_t *inBuffer, + audio_buffer_t *outBuffer); +}; + +///////////////////////////////////////////////// +// Effect library interface +///////////////////////////////////////////////// + +// Effect library interface version 3.0 +// Note that EffectsFactory.c only checks the major version component, so changes to the minor +// number can only be used for fully backwards compatible changes +#define EFFECT_LIBRARY_API_VERSION EFFECT_MAKE_API_VERSION(3,0) + +#define AUDIO_EFFECT_LIBRARY_TAG ((('A') << 24) | (('E') << 16) | (('L') << 8) | ('T')) + +// Every effect library must have a data structure named AUDIO_EFFECT_LIBRARY_INFO_SYM +// and the fields of this data structure must begin with audio_effect_library_t + +typedef struct audio_effect_library_s { + // tag must be initialized to AUDIO_EFFECT_LIBRARY_TAG + uint32_t tag; + // Version of the effect library API : 0xMMMMmmmm MMMM: Major, mmmm: minor + uint32_t version; + // Name of this library + const char *name; + // Author/owner/implementor of the library + const char *implementor; + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: create_effect + // + // Description: Creates an effect engine of the specified implementation uuid and + // returns an effect control interface on this engine. The function will allocate the + // resources for an instance of the requested effect engine and return + // a handle on the effect control interface. + // + // Input: + // uuid: pointer to the effect uuid. + // sessionId: audio session to which this effect instance will be attached. + // All effects created with the same session ID are connected in series and process + // the same signal stream. Knowing that two effects are part of the same effect + // chain can help the library implement some kind of optimizations. + // ioId: identifies the output or input stream this effect is directed to in + // audio HAL. + // For future use especially with tunneled HW accelerated effects + // + // Input/Output: + // pHandle: address where to return the effect interface handle. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid pEffectUuid or pHandle + // -ENOENT no effect with this uuid found + // *pHandle: updated with the effect interface handle. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*create_effect)(const effect_uuid_t *uuid, + int32_t sessionId, + int32_t ioId, + effect_handle_t *pHandle); + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: release_effect + // + // Description: Releases the effect engine whose handle is given as argument. + // All resources allocated to this particular instance of the effect are + // released. + // + // Input: + // handle: handle on the effect interface to be released. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid interface handle + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*release_effect)(effect_handle_t handle); + + //////////////////////////////////////////////////////////////////////////////// + // + // Function: get_descriptor + // + // Description: Returns the descriptor of the effect engine which implementation UUID is + // given as argument. + // + // Input/Output: + // uuid: pointer to the effect uuid. + // pDescriptor: address where to return the effect descriptor. + // + // Output: + // returned value: 0 successful operation. + // -ENODEV library failed to initialize + // -EINVAL invalid pDescriptor or uuid + // *pDescriptor: updated with the effect descriptor. + // + //////////////////////////////////////////////////////////////////////////////// + int32_t (*get_descriptor)(const effect_uuid_t *uuid, + effect_descriptor_t *pDescriptor); +} audio_effect_library_t; + +// Name of the hal_module_info +#define AUDIO_EFFECT_LIBRARY_INFO_SYM AELI + +// Name of the hal_module_info as a string +#define AUDIO_EFFECT_LIBRARY_INFO_SYM_AS_STR "AELI" + +__END_DECLS + +#endif // ANDROID_AUDIO_EFFECT_H diff --git a/include/hardware/audio_policy.h b/include/hardware/audio_policy.h new file mode 100644 index 00000000..bacb1e55 --- /dev/null +++ b/include/hardware/audio_policy.h @@ -0,0 +1,457 @@ +/* + * Copyright (C) 2011 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_AUDIO_POLICY_INTERFACE_H +#define ANDROID_AUDIO_POLICY_INTERFACE_H + +#include +#include +#include + +#include + +#include +#include + +__BEGIN_DECLS + +/** + * The id of this module + */ +#define AUDIO_POLICY_HARDWARE_MODULE_ID "audio_policy" + +/** + * Name of the audio devices to open + */ +#define AUDIO_POLICY_INTERFACE "policy" + +/* ---------------------------------------------------------------------------- */ + +/* + * The audio_policy and audio_policy_service_ops structs define the + * communication interfaces between the platform specific audio policy manager + * and Android generic audio policy manager. + * The platform specific audio policy manager must implement methods of the + * audio_policy struct. + * This implementation makes use of the audio_policy_service_ops to control + * the activity and configuration of audio input and output streams. + * + * The platform specific audio policy manager is in charge of the audio + * routing and volume control policies for a given platform. + * The main roles of this module are: + * - keep track of current system state (removable device connections, phone + * state, user requests...). + * System state changes and user actions are notified to audio policy + * manager with methods of the audio_policy. + * + * - process get_output() queries received when AudioTrack objects are + * created: Those queries return a handler on an output that has been + * selected, configured and opened by the audio policy manager and that + * must be used by the AudioTrack when registering to the AudioFlinger + * with the createTrack() method. + * When the AudioTrack object is released, a release_output() query + * is received and the audio policy manager can decide to close or + * reconfigure the output depending on other streams using this output and + * current system state. + * + * - similarly process get_input() and release_input() queries received from + * AudioRecord objects and configure audio inputs. + * - process volume control requests: the stream volume is converted from + * an index value (received from UI) to a float value applicable to each + * output as a function of platform specific settings and current output + * route (destination device). It also make sure that streams are not + * muted if not allowed (e.g. camera shutter sound in some countries). + */ + +/* XXX: this should be defined OUTSIDE of frameworks/base */ +struct effect_descriptor_s; + +struct audio_policy { + /* + * configuration functions + */ + + /* indicate a change in device connection status */ + int (*set_device_connection_state)(struct audio_policy *pol, + audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address); + + /* retrieve a device connection status */ + audio_policy_dev_state_t (*get_device_connection_state)( + const struct audio_policy *pol, + audio_devices_t device, + const char *device_address); + + /* indicate a change in phone state. Valid phones states are defined + * by audio_mode_t */ + void (*set_phone_state)(struct audio_policy *pol, audio_mode_t state); + + /* deprecated, never called (was "indicate a change in ringer mode") */ + void (*set_ringer_mode)(struct audio_policy *pol, uint32_t mode, + uint32_t mask); + + /* force using a specific device category for the specified usage */ + void (*set_force_use)(struct audio_policy *pol, + audio_policy_force_use_t usage, + audio_policy_forced_cfg_t config); + + /* retrieve current device category forced for a given usage */ + audio_policy_forced_cfg_t (*get_force_use)(const struct audio_policy *pol, + audio_policy_force_use_t usage); + + /* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE + * can still be muted. */ + void (*set_can_mute_enforced_audible)(struct audio_policy *pol, + bool can_mute); + + /* check proper initialization */ + int (*init_check)(const struct audio_policy *pol); + + /* + * Audio routing query functions + */ + + /* request an output appropriate for playback of the supplied stream type and + * parameters */ + audio_io_handle_t (*get_output)(struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo); + + /* indicates to the audio policy manager that the output starts being used + * by corresponding stream. */ + int (*start_output)(struct audio_policy *pol, + audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session); + + /* indicates to the audio policy manager that the output stops being used + * by corresponding stream. */ + int (*stop_output)(struct audio_policy *pol, + audio_io_handle_t output, + audio_stream_type_t stream, + audio_session_t session); + + /* releases the output. */ + void (*release_output)(struct audio_policy *pol, audio_io_handle_t output); + + /* request an input appropriate for record from the supplied device with + * supplied parameters. */ + audio_io_handle_t (*get_input)(struct audio_policy *pol, audio_source_t inputSource, + uint32_t samplingRate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_in_acoustics_t acoustics); + + /* indicates to the audio policy manager that the input starts being used */ + int (*start_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* indicates to the audio policy manager that the input stops being used. */ + int (*stop_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* releases the input. */ + void (*release_input)(struct audio_policy *pol, audio_io_handle_t input); + + /* + * volume control functions + */ + + /* initialises stream volume conversion parameters by specifying volume + * index range. The index range for each stream is defined by AudioService. */ + void (*init_stream_volume)(struct audio_policy *pol, + audio_stream_type_t stream, + int index_min, + int index_max); + + /* sets the new stream volume at a level corresponding to the supplied + * index. The index is within the range specified by init_stream_volume() */ + int (*set_stream_volume_index)(struct audio_policy *pol, + audio_stream_type_t stream, + int index); + + /* retrieve current volume index for the specified stream */ + int (*get_stream_volume_index)(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index); + + /* sets the new stream volume at a level corresponding to the supplied + * index for the specified device. + * The index is within the range specified by init_stream_volume() */ + int (*set_stream_volume_index_for_device)(struct audio_policy *pol, + audio_stream_type_t stream, + int index, + audio_devices_t device); + + /* retrieve current volume index for the specified stream for the specified device */ + int (*get_stream_volume_index_for_device)(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index, + audio_devices_t device); + + /* return the strategy corresponding to a given stream type */ + uint32_t (*get_strategy_for_stream)(const struct audio_policy *pol, + audio_stream_type_t stream); + + /* return the enabled output devices for the given stream type */ + audio_devices_t (*get_devices_for_stream)(const struct audio_policy *pol, + audio_stream_type_t stream); + + /* Audio effect management */ + audio_io_handle_t (*get_output_for_effect)(struct audio_policy *pol, + const struct effect_descriptor_s *desc); + + int (*register_effect)(struct audio_policy *pol, + const struct effect_descriptor_s *desc, + audio_io_handle_t output, + uint32_t strategy, + audio_session_t session, + int id); + + int (*unregister_effect)(struct audio_policy *pol, int id); + + int (*set_effect_enabled)(struct audio_policy *pol, int id, bool enabled); + + bool (*is_stream_active)(const struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t in_past_ms); + + bool (*is_stream_active_remotely)(const struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t in_past_ms); + + bool (*is_source_active)(const struct audio_policy *pol, + audio_source_t source); + + /* dump state */ + int (*dump)(const struct audio_policy *pol, int fd); + + /* check if offload is possible for given sample rate, bitrate, duration, ... */ + bool (*is_offload_supported)(const struct audio_policy *pol, + const audio_offload_info_t *info); +}; + + +struct audio_policy_service_ops { + /* + * Audio output Control functions + */ + + /* Opens an audio output with the requested parameters. + * + * The parameter values can indicate to use the default values in case the + * audio policy manager has no specific requirements for the output being + * opened. + * + * When the function returns, the parameter values reflect the actual + * values used by the audio hardware output stream. + * + * The audio policy manager can check if the proposed parameters are + * suitable or not and act accordingly. + */ + audio_io_handle_t (*open_output)(void *service, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + uint32_t *pLatencyMs, + audio_output_flags_t flags); + + /* creates a special output that is duplicated to the two outputs passed as + * arguments. The duplication is performed by + * a special mixer thread in the AudioFlinger. + */ + audio_io_handle_t (*open_duplicate_output)(void *service, + audio_io_handle_t output1, + audio_io_handle_t output2); + + /* closes the output stream */ + int (*close_output)(void *service, audio_io_handle_t output); + + /* suspends the output. + * + * When an output is suspended, the corresponding audio hardware output + * stream is placed in standby and the AudioTracks attached to the mixer + * thread are still processed but the output mix is discarded. + */ + int (*suspend_output)(void *service, audio_io_handle_t output); + + /* restores a suspended output. */ + int (*restore_output)(void *service, audio_io_handle_t output); + + /* */ + /* Audio input Control functions */ + /* */ + + /* opens an audio input + * deprecated - new implementations should use open_input_on_module, + * and the acoustics parameter is ignored + */ + audio_io_handle_t (*open_input)(void *service, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + audio_in_acoustics_t acoustics); + + /* closes an audio input */ + int (*close_input)(void *service, audio_io_handle_t input); + + /* */ + /* misc control functions */ + /* */ + + /* set a stream volume for a particular output. + * + * For the same user setting, a given stream type can have different + * volumes for each output (destination device) it is attached to. + */ + int (*set_stream_volume)(void *service, + audio_stream_type_t stream, + float volume, + audio_io_handle_t output, + int delay_ms); + + /* invalidate a stream type, causing a reroute to an unspecified new output */ + int (*invalidate_stream)(void *service, + audio_stream_type_t stream); + + /* function enabling to send proprietary informations directly from audio + * policy manager to audio hardware interface. */ + void (*set_parameters)(void *service, + audio_io_handle_t io_handle, + const char *kv_pairs, + int delay_ms); + + /* function enabling to receive proprietary informations directly from + * audio hardware interface to audio policy manager. + * + * Returns a pointer to a heap allocated string. The caller is responsible + * for freeing the memory for it using free(). + */ + + char * (*get_parameters)(void *service, audio_io_handle_t io_handle, + const char *keys); + + /* request the playback of a tone on the specified stream. + * used for instance to replace notification sounds when playing over a + * telephony device during a phone call. + */ + int (*start_tone)(void *service, + audio_policy_tone_t tone, + audio_stream_type_t stream); + + int (*stop_tone)(void *service); + + /* set down link audio volume. */ + int (*set_voice_volume)(void *service, + float volume, + int delay_ms); + + /* move effect to the specified output */ + int (*move_effects)(void *service, + audio_session_t session, + audio_io_handle_t src_output, + audio_io_handle_t dst_output); + + /* loads an audio hw module. + * + * The module name passed is the base name of the HW module library, e.g "primary" or "a2dp". + * The function returns a handle on the module that will be used to specify a particular + * module when calling open_output_on_module() or open_input_on_module() + */ + audio_module_handle_t (*load_hw_module)(void *service, + const char *name); + + /* Opens an audio output on a particular HW module. + * + * Same as open_output() but specifying a specific HW module on which the output must be opened. + */ + audio_io_handle_t (*open_output_on_module)(void *service, + audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask, + uint32_t *pLatencyMs, + audio_output_flags_t flags, + const audio_offload_info_t *offloadInfo); + + /* Opens an audio input on a particular HW module. + * + * Same as open_input() but specifying a specific HW module on which the input must be opened. + * Also removed deprecated acoustics parameter + */ + audio_io_handle_t (*open_input_on_module)(void *service, + audio_module_handle_t module, + audio_devices_t *pDevices, + uint32_t *pSamplingRate, + audio_format_t *pFormat, + audio_channel_mask_t *pChannelMask); + +}; + +/**********************************************************************/ + +/** + * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM + * and the fields of this data structure must begin with hw_module_t + * followed by module specific information. + */ +typedef struct audio_policy_module { + struct hw_module_t common; +} audio_policy_module_t; + +struct audio_policy_device { + /** + * Common methods of the audio policy device. This *must* be the first member of + * audio_policy_device as users of this structure will cast a hw_device_t to + * audio_policy_device pointer in contexts where it's known the hw_device_t references an + * audio_policy_device. + */ + struct hw_device_t common; + + int (*create_audio_policy)(const struct audio_policy_device *device, + struct audio_policy_service_ops *aps_ops, + void *service, + struct audio_policy **ap); + + int (*destroy_audio_policy)(const struct audio_policy_device *device, + struct audio_policy *ap); +}; + +/** convenience API for opening and closing a supported device */ + +static inline int audio_policy_dev_open(const hw_module_t* module, + struct audio_policy_device** device) +{ + return module->methods->open(module, AUDIO_POLICY_INTERFACE, + (hw_device_t**)device); +} + +static inline int audio_policy_dev_close(struct audio_policy_device* device) +{ + return device->common.close(&device->common); +} + + +__END_DECLS + +#endif // ANDROID_AUDIO_POLICY_INTERFACE_H diff --git a/modules/audio/Android.bp b/modules/audio/Android.bp index 7929c66c..a7467c29 100644 --- a/modules/audio/Android.bp +++ b/modules/audio/Android.bp @@ -23,10 +23,7 @@ cc_library_shared { relative_install_path: "hw", proprietary: true, srcs: ["audio_hw.c"], - header_libs: [ - "libhardware_headers", - "android.hardware.audio.common.legacy@2.0", - ], + header_libs: ["libhardware_headers"], shared_libs: [ "liblog", ], @@ -44,10 +41,21 @@ cc_library_shared { relative_install_path: "hw", proprietary: true, srcs: ["audio_hw.c"], - header_libs: [ - "libhardware_headers", - "android.hardware.audio.common.legacy@2.0", - ], + header_libs: ["libhardware_headers"], + shared_libs: [ + "liblog", + ], + cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"], +} + +// The stub audio policy HAL module that can be used as a skeleton for +// new implementations. +cc_library_shared { + name: "audio_policy.stub", + relative_install_path: "hw", + proprietary: true, + srcs: ["audio_policy.c"], + header_libs: ["libhardware_headers"], shared_libs: [ "liblog", ], diff --git a/modules/audio/audio_policy.c b/modules/audio/audio_policy.c new file mode 100644 index 00000000..4f9cd5a5 --- /dev/null +++ b/modules/audio/audio_policy.c @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#define LOG_TAG "audio_policy_default" +//#define LOG_NDEBUG 0 + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct default_ap_module { + struct audio_policy_module module; +}; + +struct default_ap_device { + struct audio_policy_device device; +}; + +struct default_audio_policy { + struct audio_policy policy; + + struct audio_policy_service_ops *aps_ops; + void *service; +}; + +static int ap_set_device_connection_state(struct audio_policy *pol, + audio_devices_t device, + audio_policy_dev_state_t state, + const char *device_address) +{ + return -ENOSYS; +} + +static audio_policy_dev_state_t ap_get_device_connection_state( + const struct audio_policy *pol, + audio_devices_t device, + const char *device_address) +{ + return AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE; +} + +static void ap_set_phone_state(struct audio_policy *pol, audio_mode_t state) +{ +} + +// deprecated, never called +static void ap_set_ringer_mode(struct audio_policy *pol, uint32_t mode, + uint32_t mask) +{ +} + +static void ap_set_force_use(struct audio_policy *pol, + audio_policy_force_use_t usage, + audio_policy_forced_cfg_t config) +{ +} + + /* retreive current device category forced for a given usage */ +static audio_policy_forced_cfg_t ap_get_force_use( + const struct audio_policy *pol, + audio_policy_force_use_t usage) +{ + return AUDIO_POLICY_FORCE_NONE; +} + +/* if can_mute is true, then audio streams that are marked ENFORCED_AUDIBLE + * can still be muted. */ +static void ap_set_can_mute_enforced_audible(struct audio_policy *pol, + bool can_mute) +{ +} + +static int ap_init_check(const struct audio_policy *pol) +{ + return 0; +} + +static audio_io_handle_t ap_get_output(struct audio_policy *pol, + audio_stream_type_t stream, + uint32_t sampling_rate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_output_flags_t flags, + const audio_offload_info_t *info) +{ + return 0; +} + +static int ap_start_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + return -ENOSYS; +} + +static int ap_stop_output(struct audio_policy *pol, audio_io_handle_t output, + audio_stream_type_t stream, int session) +{ + return -ENOSYS; +} + +static void ap_release_output(struct audio_policy *pol, + audio_io_handle_t output) +{ +} + +static audio_io_handle_t ap_get_input(struct audio_policy *pol, audio_source_t inputSource, + uint32_t sampling_rate, + audio_format_t format, + audio_channel_mask_t channelMask, + audio_in_acoustics_t acoustics) +{ + return 0; +} + +static int ap_start_input(struct audio_policy *pol, audio_io_handle_t input) +{ + return -ENOSYS; +} + +static int ap_stop_input(struct audio_policy *pol, audio_io_handle_t input) +{ + return -ENOSYS; +} + +static void ap_release_input(struct audio_policy *pol, audio_io_handle_t input) +{ +} + +static void ap_init_stream_volume(struct audio_policy *pol, + audio_stream_type_t stream, int index_min, + int index_max) +{ +} + +static int ap_set_stream_volume_index(struct audio_policy *pol, + audio_stream_type_t stream, + int index) +{ + return -ENOSYS; +} + +static int ap_get_stream_volume_index(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index) +{ + return -ENOSYS; +} + +static int ap_set_stream_volume_index_for_device(struct audio_policy *pol, + audio_stream_type_t stream, + int index, + audio_devices_t device) +{ + return -ENOSYS; +} + +static int ap_get_stream_volume_index_for_device(const struct audio_policy *pol, + audio_stream_type_t stream, + int *index, + audio_devices_t device) +{ + return -ENOSYS; +} + +static uint32_t ap_get_strategy_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + return 0; +} + +static audio_devices_t ap_get_devices_for_stream(const struct audio_policy *pol, + audio_stream_type_t stream) +{ + return 0; +} + +static audio_io_handle_t ap_get_output_for_effect(struct audio_policy *pol, + const struct effect_descriptor_s *desc) +{ + return 0; +} + +static int ap_register_effect(struct audio_policy *pol, + const struct effect_descriptor_s *desc, + audio_io_handle_t output, + uint32_t strategy, + int session, + int id) +{ + return -ENOSYS; +} + +static int ap_unregister_effect(struct audio_policy *pol, int id) +{ + return -ENOSYS; +} + +static int ap_set_effect_enabled(struct audio_policy *pol, int id, bool enabled) +{ + return -ENOSYS; +} + +static bool ap_is_stream_active(const struct audio_policy *pol, audio_stream_type_t stream, + uint32_t in_past_ms) +{ + return false; +} + +static int ap_dump(const struct audio_policy *pol, int fd) +{ + return -ENOSYS; +} + +static bool ap_is_offload_supported(const struct audio_policy *pol, + const audio_offload_info_t *info) +{ + return false; +} + +static int create_default_ap(const struct audio_policy_device *device, + struct audio_policy_service_ops *aps_ops, + void *service, + struct audio_policy **ap) +{ + struct default_audio_policy *dap; + + *ap = NULL; + + if (!service || !aps_ops) + return -EINVAL; + + dap = (struct default_audio_policy *)calloc(1, sizeof(*dap)); + if (!dap) + return -ENOMEM; + + dap->policy.set_device_connection_state = ap_set_device_connection_state; + dap->policy.get_device_connection_state = ap_get_device_connection_state; + dap->policy.set_phone_state = ap_set_phone_state; + dap->policy.set_ringer_mode = ap_set_ringer_mode; + dap->policy.set_force_use = ap_set_force_use; + dap->policy.get_force_use = ap_get_force_use; + dap->policy.set_can_mute_enforced_audible = + ap_set_can_mute_enforced_audible; + dap->policy.init_check = ap_init_check; + dap->policy.get_output = ap_get_output; + dap->policy.start_output = ap_start_output; + dap->policy.stop_output = ap_stop_output; + dap->policy.release_output = ap_release_output; + dap->policy.get_input = ap_get_input; + dap->policy.start_input = ap_start_input; + dap->policy.stop_input = ap_stop_input; + dap->policy.release_input = ap_release_input; + dap->policy.init_stream_volume = ap_init_stream_volume; + dap->policy.set_stream_volume_index = ap_set_stream_volume_index; + dap->policy.get_stream_volume_index = ap_get_stream_volume_index; + dap->policy.set_stream_volume_index_for_device = ap_set_stream_volume_index_for_device; + dap->policy.get_stream_volume_index_for_device = ap_get_stream_volume_index_for_device; + dap->policy.get_strategy_for_stream = ap_get_strategy_for_stream; + dap->policy.get_devices_for_stream = ap_get_devices_for_stream; + dap->policy.get_output_for_effect = ap_get_output_for_effect; + dap->policy.register_effect = ap_register_effect; + dap->policy.unregister_effect = ap_unregister_effect; + dap->policy.set_effect_enabled = ap_set_effect_enabled; + dap->policy.is_stream_active = ap_is_stream_active; + dap->policy.dump = ap_dump; + + dap->policy.is_offload_supported = ap_is_offload_supported; + + dap->service = service; + dap->aps_ops = aps_ops; + + *ap = &dap->policy; + return 0; +} + +static int destroy_default_ap(const struct audio_policy_device *ap_dev, + struct audio_policy *ap) +{ + free(ap); + return 0; +} + +static int default_ap_dev_close(hw_device_t* device) +{ + free(device); + return 0; +} + +static int default_ap_dev_open(const hw_module_t* module, const char* name, + hw_device_t** device) +{ + struct default_ap_device *dev; + + *device = NULL; + + if (strcmp(name, AUDIO_POLICY_INTERFACE) != 0) + return -EINVAL; + + dev = (struct default_ap_device *)calloc(1, sizeof(*dev)); + if (!dev) + return -ENOMEM; + + dev->device.common.tag = HARDWARE_DEVICE_TAG; + dev->device.common.version = 0; + dev->device.common.module = (hw_module_t *)module; + dev->device.common.close = default_ap_dev_close; + dev->device.create_audio_policy = create_default_ap; + dev->device.destroy_audio_policy = destroy_default_ap; + + *device = &dev->device.common; + + return 0; +} + +static struct hw_module_methods_t default_ap_module_methods = { + .open = default_ap_dev_open, +}; + +struct default_ap_module HAL_MODULE_INFO_SYM = { + .module = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .version_major = 1, + .version_minor = 0, + .id = AUDIO_POLICY_HARDWARE_MODULE_ID, + .name = "Default audio policy HAL", + .author = "The Android Open Source Project", + .methods = &default_ap_module_methods, + }, + }, +}; diff --git a/modules/audio_remote_submix/Android.bp b/modules/audio_remote_submix/Android.bp index 578949ed..c7d018c0 100644 --- a/modules/audio_remote_submix/Android.bp +++ b/modules/audio_remote_submix/Android.bp @@ -17,15 +17,16 @@ cc_library_shared { relative_install_path: "hw", vendor: true, srcs: ["audio_hw.cpp"], - + include_dirs: [ + "system/media/audio_utils/include", + ], shared_libs: [ "liblog", "libcutils", "libutils", - "libnbaio_mono@2.0", - "libaudioutils", + "libnbaio_mono", ], - static_libs: ["libmedia_helper@2.0"], + static_libs: ["libmedia_helper"], cflags: ["-Wno-unused-parameter"], diff --git a/modules/usbaudio/Android.bp b/modules/usbaudio/Android.bp index ecc74fbd..c7d403f5 100644 --- a/modules/usbaudio/Android.bp +++ b/modules/usbaudio/Android.bp @@ -25,7 +25,5 @@ cc_library_shared { "libalsautils", ], cflags: ["-Wno-unused-parameter"], - header_libs: [ - "android.hardware.audio.common.legacy@2.0", - ], + header_libs: ["libhardware_headers"], } From fd05d13edcf20c04c40467e9445f8f442b7667ad Mon Sep 17 00:00:00 2001 From: Peiyong Lin Date: Mon, 22 Jan 2018 12:23:25 -0800 Subject: [PATCH 26/50] [HWC] Add setLayerFloatColor API. This patch adds the struct of float color, and setLayerFloatColor API so that SurfaceFlinger can set the layer color with more bits on each channel. Currently the display calibration tool require 10-bits support. BUG: 69970838 Test: make locally and applied on device Change-Id: I8bab335cc4fbc41a3eb18306a8831d1e9a9a219a --- include/hardware/hwcomposer2.h | 24 +++++++++++++++++++++++- include/hardware/hwcomposer_defs.h | 7 +++++++ 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h index 11c9bdd0..a052962a 100644 --- a/include/hardware/hwcomposer2.h +++ b/include/hardware/hwcomposer2.h @@ -114,7 +114,7 @@ typedef enum { * presentDisplay should fail as fast as possible in the case a * validateDisplay step is needed. */ - HWC2_CAPABILITY_SKIP_VALIDATE= 4, + HWC2_CAPABILITY_SKIP_VALIDATE = 4, } hwc2_capability_t; /* Possible composition types for a given layer */ @@ -262,6 +262,7 @@ typedef enum { HWC2_FUNCTION_SET_POWER_MODE, HWC2_FUNCTION_SET_VSYNC_ENABLED, HWC2_FUNCTION_VALIDATE_DISPLAY, + HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, } hwc2_function_descriptor_t; /* Layer requests returned from getDisplayRequests */ @@ -479,6 +480,7 @@ static inline const char* getFunctionDescriptorName( case HWC2_FUNCTION_SET_POWER_MODE: return "SetPowerMode"; case HWC2_FUNCTION_SET_VSYNC_ENABLED: return "SetVsyncEnabled"; case HWC2_FUNCTION_VALIDATE_DISPLAY: return "ValidateDisplay"; + case HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR: return "SetLayerFloatColor"; default: return "Unknown"; } } @@ -668,6 +670,7 @@ enum class FunctionDescriptor : int32_t { SetPowerMode = HWC2_FUNCTION_SET_POWER_MODE, SetVsyncEnabled = HWC2_FUNCTION_SET_VSYNC_ENABLED, ValidateDisplay = HWC2_FUNCTION_VALIDATE_DISPLAY, + SetLayerFloatColor = HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, }; TO_STRING(hwc2_function_descriptor_t, FunctionDescriptor, getFunctionDescriptorName) @@ -1805,6 +1808,25 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_LAYER_COLOR)( hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, hwc_color_t color); +/* setLayerFloatColor(..., color) + * Descriptor: HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR + * Provided by HWC2 devices which don't return nullptr function pointer. + * + * Sets the color of the given layer. If the composition type of the layer is + * not HWC2_COMPOSITION_SOLID_COLOR, this call must return HWC2_ERROR_NONE and + * have no other effect. + * + * Parameters: + * color - the new color in float type, rage is [0.0, 1.0], the colorspace is + * defined by the dataspace that gets set by calling setLayerDataspace. + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_LAYER - an invalid layer handle was passed in + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_LAYER_FLOAT_COLOR)( + hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, + hwc_float_color_t color); + /* setLayerCompositionType(..., type) * Descriptor: HWC2_FUNCTION_SET_LAYER_COMPOSITION_TYPE * Must be provided by all HWC2 devices diff --git a/include/hardware/hwcomposer_defs.h b/include/hardware/hwcomposer_defs.h index 1e81e6e6..fd373e31 100644 --- a/include/hardware/hwcomposer_defs.h +++ b/include/hardware/hwcomposer_defs.h @@ -58,6 +58,13 @@ typedef struct hwc_color { uint8_t a; } hwc_color_t; +typedef struct hwc_float_color { + float r; + float g; + float b; + float a; +} hwc_float_color_t; + typedef struct hwc_frect { float left; float top; From 9df082e93368ae2cc86e706f1f106a4422df1e42 Mon Sep 17 00:00:00 2001 From: Dmitry Shmidt Date: Tue, 23 Jan 2018 16:30:08 -0800 Subject: [PATCH 27/50] camera 3_4: Fix compilation errors Compile Error: hardware/libhardware/modules/camera/3_4/camera.cpp:502:9: error: non-constant-expression cannot be narrowed from type 'std::__1::vector >::size_type' (aka 'unsigned long') to 'uint32_t' (aka 'unsigned int') in initializer list [-Wc++11-narrowing] request->output_buffers.size(), ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Test: Add to device.mk USE_CAMERA_V4L2_HAL := true PRODUCT_PACKAGES += camera.v4l2 mma Change-Id: Ia6bbd6bac06540214d2c6167a8826f3f4c946e57 Signed-off-by: Dmitry Shmidt --- modules/camera/3_4/camera.cpp | 2 +- modules/camera/3_4/request_tracker_test.cpp | 2 +- modules/camera/3_4/static_properties_test.cpp | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/camera/3_4/camera.cpp b/modules/camera/3_4/camera.cpp index 0f9e3784..79dca0b8 100644 --- a/modules/camera/3_4/camera.cpp +++ b/modules/camera/3_4/camera.cpp @@ -500,7 +500,7 @@ void Camera::sendResult(std::shared_ptr request) { camera3_capture_result_t result { request->frame_number, request->settings.getAndLock(), - request->output_buffers.size(), + static_cast(request->output_buffers.size()), request->output_buffers.data(), request->input_buffer.get(), 1 // Total result; only 1 part. diff --git a/modules/camera/3_4/request_tracker_test.cpp b/modules/camera/3_4/request_tracker_test.cpp index a68ff57f..8b73bd89 100644 --- a/modules/camera/3_4/request_tracker_test.cpp +++ b/modules/camera/3_4/request_tracker_test.cpp @@ -35,7 +35,7 @@ class RequestTrackerTest : public Test { stream2_.max_buffers = 3; dut_.reset(new RequestTracker()); streams_ = {&stream1_, &stream2_}; - camera3_stream_configuration_t config{streams_.size(), streams_.data(), 0}; + camera3_stream_configuration_t config{static_cast(streams_.size()), streams_.data(), 0}; dut_->SetStreamConfiguration(config); } diff --git a/modules/camera/3_4/static_properties_test.cpp b/modules/camera/3_4/static_properties_test.cpp index e78e3437..2cdb9d4d 100644 --- a/modules/camera/3_4/static_properties_test.cpp +++ b/modules/camera/3_4/static_properties_test.cpp @@ -107,7 +107,7 @@ class StaticPropertiesTest : public Test { stream_addresses.push_back(&streams[i]); } camera3_stream_configuration_t config = { - stream_addresses.size(), + static_cast(stream_addresses.size()), stream_addresses.data(), CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE}; PrepareDefaultDUT(); @@ -443,7 +443,7 @@ TEST_F(StaticPropertiesTest, ConfigureEmptyStreams) { TEST_F(StaticPropertiesTest, ConfigureNullStreams) { std::vector streams(2, nullptr); camera3_stream_configuration_t config = { - streams.size(), streams.data(), CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE}; + static_cast(streams.size()), streams.data(), CAMERA3_STREAM_CONFIGURATION_NORMAL_MODE}; PrepareDefaultDUT(); EXPECT_FALSE(dut_->StreamConfigurationSupported(&config)); } From 1d4c09e83ee7cc48210e67ed2da9b0cc10f0a1b7 Mon Sep 17 00:00:00 2001 From: Shuzhen Wang Date: Sun, 31 Dec 2017 16:57:11 -0800 Subject: [PATCH 28/50] camera3: Add physical camera id field in capture result - Add an array of physical camera ids and metadata when physical cameras are requested within a logical multi-camera. - Physical camera ids and metadata are only necessary for the final capture_results, not the partial result. - Physical camera ids and metadata must not be populated if no physical camera is requested. Test: Compile Bug: 64691172 Change-Id: I78b20fe3d0c6462abf95b8fe7e3b4c66b3acefdf --- include/hardware/camera3.h | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index ad088835..a58b8b4f 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -2498,6 +2498,37 @@ typedef struct camera3_capture_result { */ uint32_t partial_result; + /** + * >= CAMERA_DEVICE_API_VERSION_3_5: + * + * Specifies the number of physical camera metadata this capture result + * contains. It must be equal to the number of physical cameras being + * requested from. + * + * If the current camera device is not a logical multi-camera, or the + * corresponding capture_request doesn't request on any physical camera, + * this field must be 0. + */ + uint32_t num_physcam_metadata; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_5: + * + * An array of strings containing the physical camera ids for the returned + * physical camera metadata. The length of the array is + * num_physcam_metadata. + */ + const char **physcam_ids; + + /** + * >= CAMERA_DEVICE_API_VERSION_3_5: + * + * The array of physical camera metadata for the physical cameras being + * requested upon. This array should have a 1-to-1 mapping with the + * physcam_ids. The length of the array is num_physcam_metadata. + */ + const camera_metadata_t **physcam_metadata; + } camera3_capture_result_t; /********************************************************************** From 437ce43787ea0a114483b25944e4efb65d91578d Mon Sep 17 00:00:00 2001 From: Courtney Goeltzenleuchter Date: Sun, 26 Feb 2017 14:39:34 -0700 Subject: [PATCH 29/50] Add support for HDR metadata (SMPTE2086) Add HWC interface to pass in SMPTE2086 & CTA 861.3 metadata. Test: TBD CTS test Bug: 29940137 Change-Id: Ib99787752441b8a883864cc8adc8431478a15ba7 --- include/hardware/hwcomposer2.h | 216 +++++++++++++++++++++++++++++++++ 1 file changed, 216 insertions(+) diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h index a052962a..7b7db108 100644 --- a/include/hardware/hwcomposer2.h +++ b/include/hardware/hwcomposer2.h @@ -263,6 +263,11 @@ typedef enum { HWC2_FUNCTION_SET_VSYNC_ENABLED, HWC2_FUNCTION_VALIDATE_DISPLAY, HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, + HWC2_FUNCTION_SET_PER_FRAME_METADATA, + HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS, + HWC2_FUNCTION_SET_READBACK_BUFFER, + HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES, + HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE } hwc2_function_descriptor_t; /* Layer requests returned from getDisplayRequests */ @@ -312,6 +317,33 @@ typedef enum { HWC2_VSYNC_DISABLE = 2, } hwc2_vsync_t; +/* MUST match HIDL's V2_2::IComposerClient::PerFrameMetadataKey */ +typedef enum { + /* SMPTE ST 2084:2014. + * Coordinates defined in CIE 1931 xy chromaticity space + */ + HWC2_DISPLAY_RED_PRIMARY_X = 0, + HWC2_DISPLAY_RED_PRIMARY_Y = 1, + HWC2_DISPLAY_GREEN_PRIMARY_X = 2, + HWC2_DISPLAY_GREEN_PRIMARY_Y = 3, + HWC2_DISPLAY_BLUE_PRIMARY_X = 4, + HWC2_DISPLAY_BLUE_PRIMARY_Y = 5, + HWC2_WHITE_POINT_X = 6, + HWC2_WHITE_POINT_Y = 7, + /* SMPTE ST 2084:2014. + * Units: nits + * max as defined by ST 2048: 10,000 nits + */ + HWC2_MAX_LUMINANCE = 8, + HWC2_MIN_LUMINANCE = 9, + + /* CTA 861.3 + * Units: nits + */ + HWC2_MAX_CONTENT_LIGHT_LEVEL = 10, + HWC2_MAX_FRAME_AVERAGE_LIGHT_LEVEL = 11, +} hwc2_per_frame_metadata_key_t; + /* * Stringification Functions */ @@ -481,6 +513,11 @@ static inline const char* getFunctionDescriptorName( case HWC2_FUNCTION_SET_VSYNC_ENABLED: return "SetVsyncEnabled"; case HWC2_FUNCTION_VALIDATE_DISPLAY: return "ValidateDisplay"; case HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR: return "SetLayerFloatColor"; + case HWC2_FUNCTION_SET_PER_FRAME_METADATA: return "SetPerFrameMetadata"; + case HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS: return "GetPerFrameMetadataKeys"; + case HWC2_FUNCTION_SET_READBACK_BUFFER: return "SetReadbackBuffer"; + case HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES: return "GetReadbackBufferAttributes"; + case HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE: return "GetReadbackBufferFence"; default: return "Unknown"; } } @@ -671,6 +708,11 @@ enum class FunctionDescriptor : int32_t { SetVsyncEnabled = HWC2_FUNCTION_SET_VSYNC_ENABLED, ValidateDisplay = HWC2_FUNCTION_VALIDATE_DISPLAY, SetLayerFloatColor = HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, + SetPerFrameMetadata = HWC2_FUNCTION_SET_PER_FRAME_METADATA, + GetPerFrameMetadataKeys = HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS, + SetReadbackBuffer = HWC2_FUNCTION_SET_READBACK_BUFFER, + GetReadbackBufferAttributes = HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES, + GetReadbackBufferFence = HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE, }; TO_STRING(hwc2_function_descriptor_t, FunctionDescriptor, getFunctionDescriptorName) @@ -1540,6 +1582,62 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_COLOR_TRANSFORM)( hwc2_device_t* device, hwc2_display_t display, const float* matrix, int32_t /*android_color_transform_t*/ hint); +/* getPerFrameMetadataKeys(..., outKeys) + * Descriptor: HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS + * Optional for HWC2 devices + * + * If supported (getFunction(HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS) is non-null), + * getPerFrameMetadataKeys returns the list of supported PerFrameMetadataKeys + * which are invariant with regard to the active configuration. + * + * Devices which are not HDR-capable, must return null when getFunction is called + * with HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS. + * + * If outKeys is NULL, the required number of PerFrameMetadataKey keys + * must be returned in outNumKeys. + * + * Parameters: + * outNumKeys - if outKeys is NULL, the number of keys which would have + * been returned; if outKeys is not NULL, the number of keys stored in + * outKeys, which must not exceed the value stored in outNumKeys prior + * to the call; pointer will be non-NULL + * outKeys - an array of hwc2_per_frame_metadata_key_t keys + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_PER_FRAME_METADATA_KEYS)( + hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumKeys, + int32_t* /*hwc2_per_frame_metadata_key_t*/ outKeys); + +/* setPerFrameMetadata(..., numMetadata, metadata) + * Descriptor: HWC2_FUNCTION_SET_PER_FRAME_METADATA + * Optional for HWC2 devices + * + * If supported (getFunction(HWC2_FUNCTION_SET_PER_FRAME_METADATA) is non-null), + * sets the metadata for the given display for all following frames. + * + * Upon returning from this function, the metadata change must have + * fully taken effect. + * + * This function will only be called if getPerFrameMetadataKeys is non-NULL + * and returns at least one key. + * + * Parameters: + * numKeys is the number of elements in each of the keys and metadata arrays + * outKeys is a pointer to the array of keys. + * outMetadata is a pointer to the corresponding array of metadata. + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_BAD_PARAMETER - metadata is not valid + * HWC2_ERROR_UNSUPPORTED - metadata is not supported on this display + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_PER_FRAME_METADATA)( + hwc2_device_t* device, hwc2_display_t display, + uint32_t numMetadata, const int32_t* /*hw2_per_frame_metadata_key_t*/ outKeys, + const float* outMetadata); + /* setOutputBuffer(..., buffer, releaseFence) * Descriptor: HWC2_FUNCTION_SET_OUTPUT_BUFFER * Must be provided by all HWC2 devices @@ -1594,6 +1692,124 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_POWER_MODE)( hwc2_device_t* device, hwc2_display_t display, int32_t /*hwc2_power_mode_t*/ mode); +/* getReadbackBufferAttributes(..., outFormat, outDataspace) + * Optional for HWC2 devices + * + * Returns the format which should be used when allocating a buffer for use by + * device readback as well as the dataspace in which its contents should be + * interpreted. + * + * If readback is not supported by this HWC implementation, this call will also + * be able to return HWC2_ERROR_UNSUPPORTED so we can fall back to another method. + * Returning NULL to a getFunction request for this function will also indicate + * that readback is not supported. + * + * The width and height of this buffer will be those of the currently-active + * display configuration, and the usage flags will consist of the following: + * BufferUsage::CPU_READ | BufferUsage::GPU_TEXTURE | + * BufferUsage::COMPOSER_OUTPUT + * + * The format and dataspace provided must be sufficient such that if a + * correctly-configured buffer is passed into setReadbackBuffer, filled by + * the device, and then displayed by the client as a full-screen buffer, the + * output of the display remains the same (subject to the note about protected + * content in the description of setReadbackBuffer). + * + * Parameters: + * outFormat - the format the client should use when allocating a device + * readback buffer + * outDataspace - the dataspace the client will use when interpreting the + * contents of a device readback buffer + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_UNSUPPORTED - mode was a valid power mode, but is not supported + * + * See also: + * setReadbackBuffer + * getReadbackBufferFence + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES)( + hwc2_device_t* device, hwc2_display_t display, + int32_t* /*android_pixel_format_t*/ outFormat, + int32_t* /*android_dataspace_t*/ outDataspace); + +/* getReadbackBufferFence(..., outFence) + * Optional for HWC2 devices + * + * Returns an acquire sync fence file descriptor which will signal when the + * buffer provided to setReadbackBuffer has been filled by the device and is + * safe for the client to read. + * + * If it is already safe to read from this buffer, -1 may be returned instead. + * The client takes ownership of this file descriptor and is responsible for + * closing it when it is no longer needed. + * + * This function will be called immediately after the composition cycle being + * captured into the readback buffer. The complete ordering of a readback buffer + * capture is as follows: + * + * getReadbackBufferAttributes + * // Readback buffer is allocated + * // Many frames may pass + * + * setReadbackBuffer + * validateDisplay + * presentDisplay + * getReadbackBufferFence + * // Implicitly wait on the acquire fence before accessing the buffer + * + * Parameters: + * outFence - a sync fence file descriptor as described above; pointer + * will be non-NULL + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_UNSUPPORTED - mode was a valid power mode, but is not supported + * + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_READBACK_BUFFER_FENCE)( + hwc2_device_t* device, hwc2_display_t display, + int32_t* outFence); + +/* setReadbackBuffer(..., buffer, releaseFence) + * Optional for HWC2 devices + * + * Sets the readback buffer to be filled with the contents of the next + * composition performed for this display (i.e., the contents present at the + * time of the next validateDisplay/presentDisplay cycle). + * + * This buffer will have been allocated as described in + * getReadbackBufferAttributes and will be interpreted as being in the dataspace + * provided by the same. + * + * If there is hardware protected content on the display at the time of the next + * composition, the area of the readback buffer covered by such content must be + * completely black. Any areas of the buffer not covered by such content may + * optionally be black as well. + * + * The release fence file descriptor provided works identically to the one + * described for setOutputBuffer. + * + * This function will not be called between any call to validateDisplay and a + * subsequent call to presentDisplay. + * + * Parameters: + * buffer - the new readback buffer + * releaseFence - a sync fence file descriptor as described in setOutputBuffer + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_BAD_PARAMETER - the new readback buffer handle was invalid + * + * See also: + * getReadbackBufferAttributes + * getReadbackBufferFence + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_READBACK_BUFFER)( + hwc2_device_t* device, hwc2_display_t display, + buffer_handle_t buffer, int32_t releaseFence); + /* setVsyncEnabled(..., enabled) * Descriptor: HWC2_FUNCTION_SET_VSYNC_ENABLED * Must be provided by all HWC2 devices From dc9505de44c70e701cdf27c7f7d8d9de5217f4b6 Mon Sep 17 00:00:00 2001 From: "Brian C. Young" Date: Thu, 16 Nov 2017 15:45:19 -0800 Subject: [PATCH 30/50] Add "Unlocked device required" parameter to keys Add a keymaster parameter for keys that should be inaccessible when the device screen is locked. "Locked" here is a state where the device can be used or accessed without any further trust factor such as a PIN, password, fingerprint, or trusted face or voice. This parameter is added to the Java keystore interface for key creation and import, as well as enums specified by and for the native keystore process. Test: go/asym-write-test-plan Bug: 67752510 Change-Id: Ic1ec3bde05f8a28e20b9443b7f0078749921f297 --- include/hardware/keymaster_defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 6e812f29..25a4faac 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -112,6 +112,8 @@ typedef enum { KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout * if device is still on-body (requires secure * on-body sensor. */ + KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 508, /* Require the device screen to be unlocked if the + * key is used. */ /* Application access control */ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Specified to indicate key is usable by all @@ -452,6 +454,7 @@ typedef enum { KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64, KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65, KM_ERROR_CANNOT_ATTEST_IDS = -66, + KM_ERROR_DEVICE_LOCKED = -71, KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, From 82e4dc70f4aca4d0cbd980297eae01e6856a4b98 Mon Sep 17 00:00:00 2001 From: Hongwei Wang Date: Tue, 16 Jan 2018 17:29:38 -0800 Subject: [PATCH 31/50] Removes vehicle.default target Bug: 72179784 Test: None Change-Id: Ia96ef01c98565deb8920d1df2eee31149a2a9338 --- include/hardware/vehicle.h | 2170 ------------------------- modules/vehicle/Android.bp | 34 - modules/vehicle/timeUtil.cpp | 24 - modules/vehicle/vehicle.c | 579 ------- tests/vehicle/Android.bp | 48 - tests/vehicle/README | 73 - tests/vehicle/vehicle-hal-tool.c | 537 ------ tests/vehicle/vehicle_test_fixtures.h | 97 -- tests/vehicle/vehicle_tests.cpp | 129 -- 9 files changed, 3691 deletions(-) delete mode 100644 include/hardware/vehicle.h delete mode 100644 modules/vehicle/Android.bp delete mode 100644 modules/vehicle/timeUtil.cpp delete mode 100644 modules/vehicle/vehicle.c delete mode 100644 tests/vehicle/Android.bp delete mode 100644 tests/vehicle/README delete mode 100644 tests/vehicle/vehicle-hal-tool.c delete mode 100644 tests/vehicle/vehicle_test_fixtures.h delete mode 100644 tests/vehicle/vehicle_tests.cpp diff --git a/include/hardware/vehicle.h b/include/hardware/vehicle.h deleted file mode 100644 index aa92815e..00000000 --- a/include/hardware/vehicle.h +++ /dev/null @@ -1,2170 +0,0 @@ -/* - * Copyright (C) 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_VEHICLE_INTERFACE_H -#define ANDROID_VEHICLE_INTERFACE_H - -#include -#include -#include -#include -#include - -#include -#include - -__BEGIN_DECLS - -/*****************************************************************************/ - -#define VEHICLE_HEADER_VERSION 1 -#define VEHICLE_MODULE_API_VERSION_1_0 HARDWARE_MODULE_API_VERSION(1, 0) -#define VEHICLE_DEVICE_API_VERSION_1_0 HARDWARE_DEVICE_API_VERSION_2(1, 0, VEHICLE_HEADER_VERSION) - -/** - * Vehicle HAL to provide interfaces to various Car related sensors. The HAL is - * designed in a property, value maping where each property has a value which - * can be "get", "set" and "(un)subscribed" to. Subscribing will require the - * user of this HAL to provide parameters such as sampling rate. - */ - - -/* - * The id of this module - */ -#define VEHICLE_HARDWARE_MODULE_ID "vehicle" - -/** - * Name of the vehicle device to open - */ -#define VEHICLE_HARDWARE_DEVICE "vehicle_hw_device" - -/** - * Each vehicle property is defined with various annotations to specify the type of information. - * Annotations will be used by scripts to run some type check or generate some boiler-plate codes. - * Also the annotations are the specification for each property, and each HAL implementation should - * follow what is specified as annotations. - * Here is the list of annotations with explanation on what it does: - * @value_type: Type of data for this property. One of the value from vehicle_value_type should be - * set here. - * @change_mode: How this property changes. Value set is from vehicle_prop_change_mode. Some - * properties can allow either on change or continuous mode and it is up to HAL - * implementation to choose which mode to use. - * @access: Define how this property can be accessed. read only, write only or R/W from - * vehicle_prop_access - * @data_member: Name of member from vehicle_value union to access this data. - * @data_enum: enum type that should be used for the data. - * @unit: Unit of data. Should be from vehicle_unit_type. - * @config_flags: Usage of config_flags in vehicle_prop_config - * @config_array: Usage of config_array in vehicle_prop_config. When this is specified, - * @config_flags will not be used. - * @config_string: Explains the usage of config_string in vehicle_prop_config. Property with - * this annotation is expected to have additional information in config_string - * for that property to work. - * @zone_type type of zoned used. defined for zoned property - * @range_start, @range_end : define range of specific property values. - * @allow_out_of_range_value : This property allows out of range value to deliver additional - * information. Check VEHICLE_*_OUT_OF_RANGE_* for applicable values. - */ -//===== Vehicle Information ==== - -/** - * Invalid property value used for argument where invalid property gives different result. - */ -#define VEHICLE_PROPERTY_INVALID (0x0) - -/** - * VIN of vehicle - * @value_type VEHICLE_VALUE_TYPE_STRING - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member info_vin - */ -#define VEHICLE_PROPERTY_INFO_VIN (0x00000100) - -/** - * Maker name of vehicle - * @value_type VEHICLE_VALUE_TYPE_STRING - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member info_make - */ -#define VEHICLE_PROPERTY_INFO_MAKE (0x00000101) - -/** - * Model of vehicle - * @value_type VEHICLE_VALUE_TYPE_STRING - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member info_model - */ -#define VEHICLE_PROPERTY_INFO_MODEL (0x00000102) - -/** - * Model year of vehicle. - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member info_model_year - * @unit VEHICLE_UNIT_TYPE_YEAR - */ -#define VEHICLE_PROPERTY_INFO_MODEL_YEAR (0x00000103) - -/** - * Fuel capacity of the vehicle - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member info_fuel_capacity - * @unit VEHICLE_UNIT_TYPE_VEHICLE_UNIT_TYPE_MILLILITER - */ -#define VEHICLE_PROPERTY_INFO_FUEL_CAPACITY (0x00000104) - - -//==== Vehicle Performance Sensors ==== - -/** - * Current odometer value of the vehicle - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member odometer - * @unit VEHICLE_UNIT_TYPE_KILOMETER - */ -#define VEHICLE_PROPERTY_PERF_ODOMETER (0x00000204) - -/** - * Speed of the vehicle - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member vehicle_speed - * @unit VEHICLE_UNIT_TYPE_METER_PER_SEC - */ -#define VEHICLE_PROPERTY_PERF_VEHICLE_SPEED (0x00000207) - - -//==== Engine Sensors ==== - -/** - * Temperature of engine coolant - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member engine_coolant_temperature - * @unit VEHICLE_UNIT_TYPE_CELCIUS - */ -#define VEHICLE_PROPERTY_ENGINE_COOLANT_TEMP (0x00000301) - -/** - * Temperature of engine oil - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member engine_oil_temperature - * @unit VEHICLE_UNIT_TYPE_CELCIUS - */ -#define VEHICLE_PROPERTY_ENGINE_OIL_TEMP (0x00000304) -/** - * Engine rpm - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member engine_rpm - * @unit VEHICLE_UNIT_TYPE_RPM - */ -#define VEHICLE_PROPERTY_ENGINE_RPM (0x00000305) - -//==== Event Sensors ==== - -/** - * Currently selected gear - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member gear_selection - * @data_enum vehicle_gear - */ -#define VEHICLE_PROPERTY_GEAR_SELECTION (0x00000400) - -/** - * Current gear. In non-manual case, selected gear does not necessarily match the current gear - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member gear_current_gear - * @data_enum vehicle_gear - */ -#define VEHICLE_PROPERTY_CURRENT_GEAR (0x00000401) - -/** - * Parking brake state. - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member parking_brake - * @data_enum vehicle_boolean - */ -#define VEHICLE_PROPERTY_PARKING_BRAKE_ON (0x00000402) - -/** - * Driving status policy. - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member driving_status - * @data_enum vehicle_driving_status - */ -#define VEHICLE_PROPERTY_DRIVING_STATUS (0x00000404) - -/** - * Warning for fuel low level. - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member is_fuel_level_low - * @data_enum vehicle_boolean - */ -#define VEHICLE_PROPERTY_FUEL_LEVEL_LOW (0x00000405) - -/** - * Night mode or not. - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member night_mode - * @data_enum vehicle_boolean - */ -#define VEHICLE_PROPERTY_NIGHT_MODE (0x00000407) - - - -//==== HVAC Properties ==== - -/** - * Fan speed setting - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member hvac.fan_speed - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @allow_out_of_range_value : OFF - */ -#define VEHICLE_PROPERTY_HVAC_FAN_SPEED (0x00000500) - -/** - * Fan direction setting - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member hvac.fan_direction - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_enum vehicle_hvac_fan_direction - * @allow_out_of_range_value : OFF - */ -#define VEHICLE_PROPERTY_HVAC_FAN_DIRECTION (0x00000501) - -/* - * Bit flags for fan direction - */ -enum vehicle_hvac_fan_direction { - VEHICLE_HVAC_FAN_DIRECTION_FACE = 0x1, - VEHICLE_HVAC_FAN_DIRECTION_FLOOR = 0x2, - VEHICLE_HVAC_FAN_DIRECTION_FACE_AND_FLOOR = 0x3, - VEHICLE_HVAC_FAN_DIRECTION_DEFROST = 0x4, - VEHICLE_HVAC_FAN_DIRECTION_DEFROST_AND_FLOOR = 0x5 -}; - -/** - * HVAC current temperature. - * @value_type VEHICLE_VALUE_TYPE_ZONED_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.temperature_current - */ -#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_CURRENT (0x00000502) - -/** - * HVAC, target temperature set. - * @value_type VEHICLE_VALUE_TYPE_ZONED_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.temperature_set - * @allow_out_of_range_value : MIN / MAX / OFF - */ -#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_SET (0x00000503) - -/** - * On/off defrost - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_WINDOW - * @data_member hvac.defrost_on - */ -#define VEHICLE_PROPERTY_HVAC_DEFROSTER (0x00000504) - -/** - * On/off AC - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_flags Supported zones - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.ac_on - */ -#define VEHICLE_PROPERTY_HVAC_AC_ON (0x00000505) - -/** - * On/off max AC - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.max_ac_on - */ -#define VEHICLE_PROPERTY_HVAC_MAX_AC_ON (0x00000506) - -/** - * On/off max defrost - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.max_defrost_on - */ -#define VEHICLE_PROPERTY_HVAC_MAX_DEFROST_ON (0x00000507) - -/** - * On/off re-circulation - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.max_recirc_on - */ -#define VEHICLE_PROPERTY_HVAC_RECIRC_ON (0x00000508) - -/** - * On/off dual. This will be defined per each row. - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.dual_on - */ -#define VEHICLE_PROPERTY_HVAC_DUAL_ON (0x00000509) - -/** - * On/off automatic mode - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.auto_on - */ -#define VEHICLE_PROPERTY_HVAC_AUTO_ON (0x0000050A) - -/** - * Seat temperature - * - * Negative values indicate cooling. - * 0 indicates off. - * Positive values indicate heating. - * - * Some vehicles may have multiple levels of heating and cooling. The min/max - * range defines the allowable range and number of steps in each direction. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_HVAC_SEAT_TEMPERATURE (0x0000050B) - -/** - * Side Mirror Heat - * - * Increase values denote higher heating levels for side mirrors. - * 0 indicates heating is turned off. - * - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_HVAC_SIDE_MIRROR_HEAT (0x0000050C) - -/** - * Steering Wheel Temperature - * - * Sets the temperature for the steering wheel - * Positive value indicates heating. - * Negative value indicates cooling. - * 0 indicates tempreature control is off. - * - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_HVAC_STEERING_WHEEL_TEMP (0x0000050D) - -/** - * Temperature units - * - * Indicates whether the temperature is in Celsius, Fahrenheit, or a different unit. - * This parameter affects all HVAC temperatures in the system. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_enum vehicle_unit_type - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_HVAC_TEMPERATURE_UNITS (0x0000050E) - -/** - * Actual fan speed - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @data_member hvac.fan_speed - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @allow_out_of_range_value : OFF - */ -#define VEHICLE_PROPERTY_HVAC_ACTUAL_FAN_SPEED_RPM (0x0000050F) - - -/** - * Represents power state for HVAC. Some HVAC properties will require matching power to be turned on - * to get out of OFF state. For non-zoned HVAC properties, VEHICLE_ALL_ZONE corresponds to - * global power state. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_string list of HVAC properties whose power is controlled by this property. Format is - * hexa-decimal number (0x...) separated by comma like "0x500,0x503". All zones - * defined in these affected properties should be available in the property. - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @data_member hvac.power_on - */ -#define VEHICLE_PROPERTY_HVAC_POWER_ON (0x00000510) - -/** - * Fan Positions Available - * - * This is a bit mask of fan positions available for the zone. Each entry in - * vehicle_hvac_fan_direction is selected by bit position. For instance, if - * only the FAN_DIRECTION_FACE (0x1) and FAN_DIRECTION_DEFROST (0x4) are available, - * then this value shall be set to 0x12. - * - * 0x12 = (1 << 1) | (1 << 4) - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC - * @access VEHICLE_PROP_ACCESS_READ - * @data_member int32_value - * @zone_type VEHICLE_ZONE_TYPE_ZONE - * @allow_out_of_range_value : OFF - */ -#define VEHICLE_PROPERTY_HVAC_FAN_DIRECTION_AVAILABLE (0x00000511) - -/** - * Outside temperature - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member outside_temperature - * @unit VEHICLE_UNIT_TYPE_CELCIUS - */ -#define VEHICLE_PROPERTY_ENV_OUTSIDE_TEMPERATURE (0x00000703) - - -/** - * Cabin temperature - * @value_type VEHICLE_VALUE_TYPE_FLOAT - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE|VEHICLE_PROP_CHANGE_MODE_CONTINUOUS - * @access VEHICLE_PROP_ACCESS_READ - * @data_member cabin_temperature - * @unit VEHICLE_UNIT_TYPE_CELCIUS - */ -#define VEHICLE_PROPERTY_ENV_CABIN_TEMPERATURE (0x00000704) - - -/* - * Radio features. - */ -/** - * Radio presets stored on the Car radio module. The data type used is int32 - * array with the following fields: - *
    - *
  • int32_array[0]: Preset number
  • - *
  • int32_array[1]: Band type (see #RADIO_BAND_FM in - * system/core/include/system/radio.h). - *
  • int32_array[2]: Channel number
  • - *
  • int32_array[3]: Sub channel number
  • - *
- * - * NOTE: When getting a current preset config ONLY set preset number (i.e. - * int32_array[0]). For setting a preset other fields are required. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC4 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_flags Number of presets supported - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_RADIO_PRESET (0x00000801) - -/** - * Constants relevant to radio. - */ -enum vehicle_radio_consts { - /** Minimum value for the radio preset */ - VEHICLE_RADIO_PRESET_MIN_VALUE = 1, -}; - -/** - * Property to control power state of application processor. - * - * It is assumed that AP's power state is controller by separate power controller. - * - * For configuration information, vehicle_prop_config.config_flags can have bit flag combining - * values in vehicle_ap_power_state_config_type. - * - * For get / notification, data type looks like this: - * int32_array[0] : vehicle_ap_power_state_type - * int32_array[1] : additional parameter relevant for each state. should be 0 if not used. - * For set, data type looks like this: - * int32_array[0] : vehicle_ap_power_state_set_type - * int32_array[1] : additional parameter relevant for each request. should be 0 if not used. - * - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC2 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_flags Additional info on power state. Should use vehicle_ap_power_state_config_flag. - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_AP_POWER_STATE (0x00000A00) - -enum vehicle_ap_power_state_config_flag { - /** - * AP can enter deep sleep state. If not set, AP will always shutdown from - * VEHICLE_AP_POWER_STATE_SHUTDOWN_PREPARE power state. - */ - VEHICLE_AP_POWER_STATE_CONFIG_ENABLE_DEEP_SLEEP_FLAG = 0x1, - - /** - * The power controller can power on AP from off state after timeout specified in - * VEHICLE_AP_POWER_SET_SHUTDOWN_READY message. - */ - VEHICLE_AP_POWER_STATE_CONFIG_SUPPORT_TIMER_POWER_ON_FLAG = 0x2, -}; - -enum vehicle_ap_power_state { - /** vehicle HAL will never publish this state to AP */ - VEHICLE_AP_POWER_STATE_OFF = 0, - /** vehicle HAL will never publish this state to AP */ - VEHICLE_AP_POWER_STATE_DEEP_SLEEP = 1, - /** AP is on but display should be off. */ - VEHICLE_AP_POWER_STATE_ON_DISP_OFF = 2, - /** AP is on with display on. This state allows full user interaction. */ - VEHICLE_AP_POWER_STATE_ON_FULL = 3, - /** - * The power controller has requested AP to shutdown. AP can either enter sleep state or start - * full shutdown. AP can also request postponing shutdown by sending - * VEHICLE_AP_POWER_SET_SHUTDOWN_POSTPONE message. The power controller should change power - * state to this state to shutdown system. - * - * int32_array[1] : one of enum_vehicle_ap_power_state_shutdown_param_type - */ - VEHICLE_AP_POWER_STATE_SHUTDOWN_PREPARE = 4, -}; - -enum vehicle_ap_power_state_shutdown_param { - /** AP should shutdown immediately. Postponing is not allowed. */ - VEHICLE_AP_POWER_SHUTDOWN_PARAM_SHUTDOWN_IMMEDIATELY = 1, - /** AP can enter deep sleep instead of shutting down completely. */ - VEHICLE_AP_POWER_SHUTDOWN_PARAM_CAN_SLEEP = 2, - /** AP can only shutdown with postponing allowed. */ - VEHICLE_AP_POWER_SHUTDOWN_PARAM_SHUTDOWN_ONLY = 3, -}; - -enum vehicle_ap_power_set_state { - /** - * AP has finished boot up, and can start shutdown if requested by power controller. - */ - VEHICLE_AP_POWER_SET_BOOT_COMPLETE = 0x1, - /** - * AP is entering deep sleep state. How this state is implemented may vary depending on - * each H/W, but AP's power should be kept in this state. - */ - VEHICLE_AP_POWER_SET_DEEP_SLEEP_ENTRY = 0x2, - /** - * AP is exiting from deep sleep state, and is in VEHICLE_AP_POWER_STATE_SHUTDOWN_PREPARE state. - * The power controller may change state to other ON states based on the current state. - */ - VEHICLE_AP_POWER_SET_DEEP_SLEEP_EXIT = 0x3, - /** - * int32_array[1]: Time to postpone shutdown in ms. Maximum value can be 5000 ms. - * If AP needs more time, it will send another POSTPONE message before - * the previous one expires. - */ - VEHICLE_AP_POWER_SET_SHUTDOWN_POSTPONE = 0x4, - /** - * AP is starting shutting down. When system completes shutdown, everything will stop in AP - * as kernel will stop all other contexts. It is responsibility of vehicle HAL or lower level - * to synchronize that state with external power controller. As an example, some kind of ping - * with timeout in power controller can be a solution. - * - * int32_array[1]: Time to turn on AP in secs. Power controller may turn on AP after specified - * time so that AP can run tasks like update. If it is set to 0, there is no - * wake up, and power controller may not necessarily support wake-up. - * If power controller turns on AP due to timer, it should start with - * VEHICLE_AP_POWER_STATE_ON_DISP_OFF state, and after receiving - * VEHICLE_AP_POWER_SET_BOOT_COMPLETE, it shall do state transition to - * VEHICLE_AP_POWER_STATE_SHUTDOWN_PREPARE. - */ - VEHICLE_AP_POWER_SET_SHUTDOWN_START = 0x5, - /** - * User has requested to turn off headunit's display, which is detected in android side. - * The power controller may change the power state to VEHICLE_AP_POWER_STATE_ON_DISP_OFF. - */ - VEHICLE_AP_POWER_SET_DISPLAY_OFF = 0x6, - /** - * User has requested to turn on headunit's display, most probably from power key input which - * is attached to headunit. The power controller may change the power state to - * VEHICLE_AP_POWER_STATE_ON_FULL. - */ - VEHICLE_AP_POWER_SET_DISPLAY_ON = 0x7, -}; - -/** - * Property to represent brightness of the display. Some cars have single control for - * the brightness of all displays and this property is to share change in that control. - * - * If this is writable, android side can set this value when user changes display brightness - * from Settings. If this is read only, user may still change display brightness from Settings, - * but that will not be reflected to other displays. - * - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32 - */ -#define VEHICLE_PROPERTY_DISPLAY_BRIGHTNESS (0x00000A01) - - -/** - * Index in int32_array for VEHICLE_PROPERTY_AP_POWER_STATE property. - */ -enum vehicle_ap_power_state_index { - VEHICLE_AP_POWER_STATE_INDEX_STATE = 0, - VEHICLE_AP_POWER_STATE_INDEX_ADDITIONAL = 1, -}; - -/** -* Property to report bootup reason for the current power on. This is a static property that will -* not change for the whole duration until power off. For example, even if user presses power on -* button after automatic power on with door unlock, bootup reason should stay with -* VEHICLE_AP_POWER_BOOTUP_REASON_USER_UNLOCK. -* -* int32_value should be vehicle_ap_power_bootup_reason. -* -* @value_type VEHICLE_VALUE_TYPE_INT32 -* @change_mode VEHICLE_PROP_CHANGE_MODE_STATIC -* @access VEHICLE_PROP_ACCESS_READ -* @data_member int32_value -*/ -#define VEHICLE_PROPERTY_AP_POWER_BOOTUP_REASON (0x00000A02) - -/** - * Enum to represent bootup reason. - */ -enum vehicle_ap_power_bootup_reason { - /** - * Power on due to user's pressing of power key or rotating of ignition switch. - */ - VEHICLE_AP_POWER_BOOTUP_REASON_USER_POWER_ON = 0, - /** - * Automatic power on triggered by door unlock or any other kind of automatic user detection. - */ - VEHICLE_AP_POWER_BOOTUP_REASON_USER_UNLOCK = 1, - /** - * Automatic power on triggered by timer. This only happens when AP has asked wake-up after - * certain time through time specified in VEHICLE_AP_POWER_SET_SHUTDOWN_START. - */ - VEHICLE_AP_POWER_BOOTUP_REASON_TIMER = 2, -}; - - -/** - * Property to feed H/W input events to android - * - * int32_array[0] : action defined by vehicle_hw_key_input_action - * int32_array[1] : key code, should use standard android key code - * int32_array[2] : target display defined in vehicle_display. Events not tied - * to specific display should be sent to DISPLAY_MAIN. - * int32_array[3] : reserved for now. should be zero - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC4 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ - * @config_flags - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_HW_KEY_INPUT (0x00000A10) - -enum vehicle_hw_key_input_action { - /** Key down */ - VEHICLE_HW_KEY_INPUT_ACTION_DOWN = 0, - /** Key up */ - VEHICLE_HW_KEY_INPUT_ACTION_UP = 1, -}; - -enum vehicle_display { - /** center console */ - VEHICLE_DISPLAY_MAIN = 0, - VEHICLE_DISPLAY_INSTRUMENT_CLUSTER = 1, -}; - -/** - * Property to define instrument cluster information. - * For CLUSTER_TYPE_EXTERNAL_DISPLAY: - * READ: - * int32_array[0] : The current screen mode index. Screen mode is defined - * as a configuration in car service and represents which - * area of screen is renderable. - * int32_array[1] : Android can render to instrument cluster (=1) or not(=0). When this is 0, - * instrument cluster may be rendering some information in the area - * allocated for android and android side rendering is invisible. * - * int32_array[2..3] : should be zero - * WRITE from android: - * int32_array[0] : Preferred mode for android side. Depending on the app rendering to instrument - * cluster, preferred mode can change. Instrument cluster still needs to send - * event with new mode to trigger actual mode change. - * int32_array[1] : The current app context relevant for instrument cluster. Use the same flag - * with vehicle_audio_context_flag but this context represents active apps, not - * active audio. Instrument cluster side may change mode depending on the - * currently active contexts. - * int32_array[2..3] : should be zero - * When system boots up, Android side will write {0, 0, 0, 0} when it is ready to render to - * instrument cluster. Before this message, rendering from android should not be visible in the - * cluster. - * @value_type VEHICLE_VALUE_TYPE_INT32_VEC4 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @config_array 0:vehicle_instument_cluster_type 1:hw type - * @data_member int32_array - */ -#define VEHICLE_PROPERTY_INSTRUMENT_CLUSTER_INFO (0x00000A20) - -/** - * Represents instrument cluster type available in system - */ -enum vehicle_instument_cluster_type { - /** Android has no access to instument cluster */ - VEHICLE_INSTRUMENT_CLUSTER_TYPE_NONE = 0, - /** - * Instrument cluster can communicate through vehicle hal with additional - * properties to exchange meta-data - */ - VEHICLE_INSTRUMENT_CLUSTER_TYPE_HAL_INTERFACE = 1, - /** - * Instrument cluster is external display where android can render contents - */ - VEHICLE_INSTRUMENT_CLUSTER_TYPE_EXTERNAL_DISPLAY = 2, -}; - -/** - * Current date and time, encoded as Unix time. - * This value denotes the number of seconds that have elapsed since 1/1/1970. - * - * @value_type VEHICLE_VALUE_TYPE_INT64 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_SET - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int64_value - * @unit VEHICLE_UNIT_TYPE_SECS - */ -#define VEHICLE_PROPERTY_UNIX_TIME (0x00000A30) - -/** - * Current time only. - * Some vehicles may not keep track of date. This property only affects the current time, in - * seconds during the day. Thus, the max value for this parameter is 86,400 (24 * 60 * 60) - * - * @value_type VEHICLE_VALUE_TYPE_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_SET - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_value - * @unit VEHICLE_UNIT_TYPE_SECS - */ -#define VEHICLE_PROPERTY_CURRENT_TIME_IN_SECONDS (0x00000A31) - - -//==== Car Cabin Properties ==== -/** - * Most Car Cabin properties have both a MOVE and POSITION parameter associated with them. - * - * The MOVE parameter will start moving the device in the indicated direction. The magnitude - * indicates the relative speed. For instance, setting the WINDOW_MOVE parameter to +1 will roll - * the window up. Setting it to +2 (if available) will roll it up faster. - * - * The POSITION parameter will move the device to the desired position. For instance, if the - * WINDOW_POS has a range of 0-100, then setting this parameter to 50 will open the window halfway. - * Depending upon the initial position, the window may move up or down to the 50% value. - * - * OEMs may choose to implement one or both of the MOVE/POSITION parameters depending upon the - * capability of the hardware. - */ - -// Doors -/** - * Door position - * - * This is an integer in case a door may be set to a particular position. Max - * value indicates fully open, min value (0) indicates fully closed. - * - * Some vehicles (minivans) can open the door electronically. Hence, the ability - * to write this property. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_DOOR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_DOOR_POS (0x00000B00) - -/** - * Door move - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_DOOR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_DOOR_MOVE (0x00000B01) - - -/** - * Door lock - * - * 'true' indicates door is locked - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_DOOR - * @data_member boolean_value - */ -#define VEHICLE_PROPERTY_DOOR_LOCK (0x00000B02) - -// Mirrors -/** - * Mirror Z Position - * - * Positive value indicates tilt upwards, negative value is downwards - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_MIRROR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_MIRROR_Z_POS (0x00000B40) - -/** - * Mirror Z Move - * - * Positive value indicates tilt upwards, negative value is downwards - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_MIRROR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_MIRROR_Z_MOVE (0x00000B41) - -/** - * Mirror Y Position - * - * Positive value indicate tilt right, negative value is left - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_MIRROR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_MIRROR_Y_POS (0x00000B42) - -/** - * Mirror Y Move - * - * Positive value indicate tilt right, negative value is left - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_MIRROR - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_MIRROR_Y_MOVE (0x00000B43) - -/** - * Mirror Lock - * - * True indicates mirror positions are locked and not changeable - * - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member boolean_value - */ -#define VEHICLE_PROPERTY_MIRROR_LOCK (0x00000B44) - -/** - * Mirror Fold - * - * True indicates mirrors are folded - * - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member boolean_value - */ -#define VEHICLE_PROPERTY_MIRROR_FOLD (0x00000B45) - -// Seats -/** - * Seat memory select - * - * This parameter selects the memory preset to use to select the seat position. - * The minValue is always 0, and the maxValue determines the number of seat - * positions available. - * - * For instance, if the driver's seat has 3 memory presets, the maxValue will be 3. - * When the user wants to select a preset, the desired preset number (1, 2, or 3) - * is set. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_MEMORY_SELECT (0x00000B80) - -/** - * Seat memory set - * - * This setting allows the user to save the current seat position settings into - * the selected preset slot. The maxValue for each seat position shall match - * the maxValue for VEHICLE_PROPERTY_SEAT_MEMORY_SELECT. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_MEMORY_SET (0x00000B81) - -/** - * Seatbelt buckled - * - * True indicates belt is buckled. - * - * Write access indicates automatic seat buckling capabilities. There are no known cars at this - * time, but you never know... - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member boolean_value - */ -#define VEHICLE_PROPERTY_SEAT_BELT_BUCKLED (0x00000B82) - -/** - * Seatbelt height position - * - * Adjusts the shoulder belt anchor point. - * Max value indicates highest position - * Min value indicates lowest position - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_POS (0x00000B83) - -/** - * Seatbelt height move - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BELT_HEIGHT_MOVE (0x00000B84) - -/** - * Seat fore/aft position - * - * Sets the seat position forward (closer to steering wheel) and backwards. - * Max value indicates closest to wheel, min value indicates most rearward - * position. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_FORE_AFT_POS (0x00000B85) - -/** - * Seat fore/aft move - * - * Moves the seat position forward and aft. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_FORE_AFT_MOVE (0x00000B86) - -/** - * Seat backrest angle 1 position - * - * Backrest angle 1 is the actuator closest to the bottom of the seat. - * Max value indicates angling forward towards the steering wheel. - * Min value indicates full recline. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_POS (0x00000B87) - -/** - * Seat backrest angle 1 move - * - * Moves the backrest forward or recline. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_1_MOVE (0x00000B88) - -/** - * Seat backrest angle 2 position - * - * Backrest angle 2 is the next actuator up from the bottom of the seat. - * Max value indicates angling forward towards the steering wheel. - * Min value indicates full recline. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_POS (0x00000B89) - -/** - * Seat backrest angle 2 move - * - * Moves the backrest forward or recline. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_BACKREST_ANGLE_2_MOVE (0x00000B8A) - -/** - * Seat height position - * - * Sets the seat height. - * Max value indicates highest position. - * Min value indicates lowest position. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEIGHT_POS (0x00000B8B) - -/** - * Seat height move - * - * Moves the seat height. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEIGHT_MOVE (0x00000B8C) - -/** - * Seat depth position - * - * Sets the seat depth, distance from back rest to front edge of seat. - * Max value indicates longest depth position. - * Min value indicates shortest position. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_DEPTH_POS (0x00000B8D) - -/** - * Seat depth move - * - * Adjusts the seat depth. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_DEPTH_MOVE (0x00000B8E) - -/** - * Seat tilt position - * - * Sets the seat tilt. - * Max value indicates front edge of seat higher than back edge. - * Min value indicates front edge of seat lower than back edge. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_TILT_POS (0x00000B8F) - -/** - * Seat tilt move - * - * Tilts the seat. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_TILT_MOVE (0x00000B90) - -/** - * Lumber fore/aft position - * - * Pushes the lumbar support forward and backwards - * Max value indicates most forward position. - * Min value indicates most rearward position. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_POS (0x00000B91) - -/** - * Lumbar fore/aft move - * - * Adjusts the lumbar support. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_LUMBAR_FORE_AFT_MOVE (0x00000B92) - -/** - * Lumbar side support position - * - * Sets the amount of lateral lumbar support. - * Max value indicates widest lumbar setting (i.e. least support) - * Min value indicates thinnest lumbar setting. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_POS (0x00000B93) - -/** - * Lumbar side support move - * - * Adjusts the amount of lateral lumbar support. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_LUMBAR_SIDE_SUPPORT_MOVE (0x00000B94) - -/** - * Headrest height position - * - * Sets the headrest height. - * Max value indicates tallest setting. - * Min value indicates shortest setting. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_POS (0x00000B95) - -/** - * Headrest height move - * - * Moves the headrest up and down. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_HEIGHT_MOVE (0x00000B96) - -/** - * Headrest angle position - * - * Sets the angle of the headrest. - * Max value indicates most upright angle. - * Min value indicates shallowest headrest angle. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_POS (0x00000B97) - -/** - * Headrest angle move - * - * Adjusts the angle of the headrest - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_ANGLE_MOVE (0x00000B98) - -/** - * Headrest fore/aft position - * - * Adjusts the headrest forwards and backwards. - * Max value indicates position closest to front of car. - * Min value indicates position closest to rear of car. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_POS (0x00000B99) - -/** - * Headrest fore/aft move - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @zone_type VEHICLE_ZONE_TYPE_SEAT - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_SEAT_HEADREST_FORE_AFT_MOVE (0x00000B9A) - - -// Windows -/** - * Window Position - * - * Max = window up / closed - * Min = window down / open - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_WINDOW_POS (0x00000BC0) - -/** - * Window Move - * - * Max = window up / closed - * Min = window down / open - * Magnitude denotes relative speed. I.e. +2 is faster than +1 in raising the window. - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_WINDOW_MOVE (0x00000BC1) - -/** - * Window Vent Position - * - * This feature is used to control the vent feature on a sunroof. - * - * Max = vent open - * Min = vent closed - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_WINDOW_VENT_POS (0x00000BC2) - -/** - * Window Vent Move - * - * This feature is used to control the vent feature on a sunroof. - * - * Max = vent open - * Min = vent closed - * - * @value_type VEHICLE_VALUE_TYPE_ZONED_INT32 - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE|VEHICLE_PROP_ACCESS_WRITE - * @data_member int32_value - */ -#define VEHICLE_PROPERTY_WINDOW_VENT_MOVE (0x00000BC3) - -/** - * Window Lock - * - * True indicates windows are locked and can't be moved. - * - * @value_type VEHICLE_VALUE_TYPE_BOOLEAN - * @change_mode VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - * @access VEHICLE_PROP_ACCESS_READ_WRITE - * @data_member boolean_value - */ -#define VEHICLE_PROPERTY_WINDOW_LOCK (0x00000BC4) - - - -/** - * H/W specific, non-standard property can be added as necessary. Such property should use - * property number in range of [VEHICLE_PROPERTY_CUSTOM_START, VEHICLE_PROPERTY_CUSTOM_END]. - * Definition of property in this range is completely up to each HAL implementation. - * For such property, it is recommended to fill vehicle_prop_config.config_string with some - * additional information to help debugging. For example, company XYZ's custom extension may - * include config_string of "com.XYZ.some_further_details". - * @range_start - */ -#define VEHICLE_PROPERTY_CUSTOM_START (0x70000000) -/** @range_end */ -#define VEHICLE_PROPERTY_CUSTOM_END (0x73ffffff) - -/** - * Property range allocated for system's internal usage like testing. HAL should never declare - * property in this range. - * @range_start - */ -#define VEHICLE_PROPERTY_INTERNAL_START (0x74000000) -/** - * @range_end - */ -#define VEHICLE_PROPERTY_INTERNAL_END (0x74ffffff) - -/** - * Value types for various properties. - */ -enum vehicle_value_type { - VEHICLE_VALUE_TYPE_SHOUD_NOT_USE = 0x00, // value_type should never set to 0. - VEHICLE_VALUE_TYPE_STRING = 0x01, - VEHICLE_VALUE_TYPE_BYTES = 0x02, - VEHICLE_VALUE_TYPE_BOOLEAN = 0x03, - VEHICLE_VALUE_TYPE_ZONED_BOOLEAN = 0x04, - VEHICLE_VALUE_TYPE_INT64 = 0x05, - VEHICLE_VALUE_TYPE_FLOAT = 0x10, - VEHICLE_VALUE_TYPE_FLOAT_VEC2 = 0x11, - VEHICLE_VALUE_TYPE_FLOAT_VEC3 = 0x12, - VEHICLE_VALUE_TYPE_FLOAT_VEC4 = 0x13, - VEHICLE_VALUE_TYPE_INT32 = 0x20, - VEHICLE_VALUE_TYPE_INT32_VEC2 = 0x21, - VEHICLE_VALUE_TYPE_INT32_VEC3 = 0x22, - VEHICLE_VALUE_TYPE_INT32_VEC4 = 0x23, - VEHICLE_VALUE_TYPE_ZONED_FLOAT = 0x30, - VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2 = 0x31, - VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3 = 0x32, - VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4 = 0x33, - VEHICLE_VALUE_TYPE_ZONED_INT32 = 0x40, - VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2 = 0x41, - VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3 = 0x42, - VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4 = 0x43, -}; - -/** - * Units used for int or float type with no attached enum types. - */ -enum vehicle_unit_type { - VEHICLE_UNIT_TYPE_SHOULD_NOT_USE = 0x00000000, - // speed related items - VEHICLE_UNIT_TYPE_METER_PER_SEC = 0x00000001, - VEHICLE_UNIT_TYPE_RPM = 0x00000002, - VEHICLE_UNIT_TYPE_HZ = 0x00000003, - // kind of ratio - VEHICLE_UNIT_TYPE_PERCENTILE = 0x00000010, - // length - VEHICLE_UNIT_TYPE_MILLIMETER = 0x00000020, - VEHICLE_UNIT_TYPE_METER = 0x00000021, - VEHICLE_UNIT_TYPE_KILOMETER = 0x00000023, - // temperature - VEHICLE_UNIT_TYPE_CELSIUS = 0x00000030, - VEHICLE_UNIT_TYPE_FAHRENHEIT = 0x00000031, - VEHICLE_UNIT_TYPE_KELVIN = 0x00000032, - // volume - VEHICLE_UNIT_TYPE_MILLILITER = 0x00000040, - // time - VEHICLE_UNIT_TYPE_NANO_SECS = 0x00000050, - VEHICLE_UNIT_TYPE_SECS = 0x00000053, - VEHICLE_UNIT_TYPE_YEAR = 0x00000059, -}; - -/** - * This describes how value of property can change. - */ -enum vehicle_prop_change_mode { - /** - * Property of this type will *never* change. This property will not support subscription, but - * will support get - */ - VEHICLE_PROP_CHANGE_MODE_STATIC = 0x00, - /** - * Property of this type will be reported when there is a change. - * get call should return the current value. - * Set operation for this property is assumed to be asynchronous. When the property is read - * (get) after set, it may still return old value until underlying H/W backing this property - * has actually changed the state. Once state is changed, the property will dispatch changed - * value as event. - */ - VEHICLE_PROP_CHANGE_MODE_ON_CHANGE = 0x01, - /** - * Property of this type change continuously and requires fixed rate of sampling to retrieve - * the data. - */ - VEHICLE_PROP_CHANGE_MODE_CONTINUOUS = 0x02, - /** - * Property of this type may be polled to get the current value. - */ - VEHICLE_PROP_CHANGE_MODE_POLL = 0x03, - /** - * This is for property where change event should be sent only when the value is - * set from external component. Normal value change will not trigger event. - * For example, clock property can send change event only when it is set, outside android, - * for case like user setting time or time getting update. There is no need to send it - * per every value change. - */ - VEHICLE_PROP_CHANGE_MODE_ON_SET = 0x04, -}; - -/** - * Property config defines the capabilities of it. User of the API - * should first get the property config to understand the output from get() - * commands and also to ensure that set() or events commands are in sync with - * the expected output. - */ -enum vehicle_prop_access { - VEHICLE_PROP_ACCESS_READ = 0x01, - VEHICLE_PROP_ACCESS_WRITE = 0x02, - VEHICLE_PROP_ACCESS_READ_WRITE = 0x03 -}; - -/** - * These permissions define how the OEMs want to distribute their information and security they - * want to apply. On top of these restrictions, android will have additional - * 'app-level' permissions that the apps will need to ask the user before the apps have the - * information. - * This information should be kept in vehicle_prop_config.permission_model. - */ -enum vehicle_permission_model { - /** - * No special restriction, but each property can still require specific android app-level - * permission. - */ - VEHICLE_PERMISSION_NO_RESTRICTION = 0, - /** Signature only. Only APKs signed with OEM keys are allowed. */ - VEHICLE_PERMISSION_OEM_ONLY = 0x1, - /** System only. APKs built-in to system can access the property. */ - VEHICLE_PERMISSION_SYSTEM_APP_ONLY = 0x2, - /** Equivalent to “system|signature” */ - VEHICLE_PERMISSION_OEM_OR_SYSTEM_APP = 0x3 -}; - - -/** - * Special values for INT32/FLOAT (including ZONED types) - * These values represent special state, which is outside MIN/MAX range but can happen. - * For example, HVAC temperature may use out of range min / max to represent that - * it is working in full power although target temperature has separate min / max. - * OUT_OF_RANGE_OFF can represent a state where the property is powered off. - * Usually such property will have separate property to control power. - */ - -#define VEHICLE_INT_OUT_OF_RANGE_MAX (INT32_MAX) -#define VEHICLE_INT_OUT_OF_RANGE_MIN (INT32_MIN) -#define VEHICLE_INT_OUT_OF_RANGE_OFF (INT32_MIN + 1) - -#define VEHICLE_FLOAT_OUT_OF_RANGE_MAX (INFINITY) -#define VEHICLE_FLOAT_OUT_OF_RANGE_MIN (-INFINITY) -#define VEHICLE_FLOAT_OUT_OF_RANGE_OFF (NAN) - -/** - * Car states. - * - * The driving states determine what features of the UI will be accessible. - */ -enum vehicle_driving_status { - VEHICLE_DRIVING_STATUS_UNRESTRICTED = 0x00, - VEHICLE_DRIVING_STATUS_NO_VIDEO = 0x01, - VEHICLE_DRIVING_STATUS_NO_KEYBOARD_INPUT = 0x02, - VEHICLE_DRIVING_STATUS_NO_VOICE_INPUT = 0x04, - VEHICLE_DRIVING_STATUS_NO_CONFIG = 0x08, - VEHICLE_DRIVING_STATUS_LIMIT_MESSAGE_LEN = 0x10 -}; - -/** - * Various gears which can be selected by user and chosen in system. - */ -enum vehicle_gear { - // Gear selections present in both automatic and manual cars. - VEHICLE_GEAR_NEUTRAL = 0x0001, - VEHICLE_GEAR_REVERSE = 0x0002, - - // Gear selections (mostly) present only in automatic cars. - VEHICLE_GEAR_PARK = 0x0004, - VEHICLE_GEAR_DRIVE = 0x0008, - VEHICLE_GEAR_LOW = 0x0010, - - // Other possible gear selections (maybe present in manual or automatic - // cars). - VEHICLE_GEAR_1 = 0x0010, - VEHICLE_GEAR_2 = 0x0020, - VEHICLE_GEAR_3 = 0x0040, - VEHICLE_GEAR_4 = 0x0080, - VEHICLE_GEAR_5 = 0x0100, - VEHICLE_GEAR_6 = 0x0200, - VEHICLE_GEAR_7 = 0x0400, - VEHICLE_GEAR_8 = 0x0800, - VEHICLE_GEAR_9 = 0x1000 -}; - - -/** - * Various zones in the car. - * - * Zones are used for Air Conditioning purposes and divide the car into physical - * area zones. - */ -enum vehicle_zone { - VEHICLE_ZONE_ROW_1_LEFT = 0x00000001, - VEHICLE_ZONE_ROW_1_CENTER = 0x00000002, - VEHICLE_ZONE_ROW_1_RIGHT = 0x00000004, - VEHICLE_ZONE_ROW_1_ALL = 0x00000008, - VEHICLE_ZONE_ROW_2_LEFT = 0x00000010, - VEHICLE_ZONE_ROW_2_CENTER = 0x00000020, - VEHICLE_ZONE_ROW_2_RIGHT = 0x00000040, - VEHICLE_ZONE_ROW_2_ALL = 0x00000080, - VEHICLE_ZONE_ROW_3_LEFT = 0x00000100, - VEHICLE_ZONE_ROW_3_CENTER = 0x00000200, - VEHICLE_ZONE_ROW_3_RIGHT = 0x00000400, - VEHICLE_ZONE_ROW_3_ALL = 0x00000800, - VEHICLE_ZONE_ROW_4_LEFT = 0x00001000, - VEHICLE_ZONE_ROW_4_CENTER = 0x00002000, - VEHICLE_ZONE_ROW_4_RIGHT = 0x00004000, - VEHICLE_ZONE_ROW_4_ALL = 0x00008000, - VEHICLE_ZONE_ALL = 0x80000000, -}; - -/** - * Various Seats in the car. - */ -enum vehicle_seat { - VEHICLE_SEAT_ROW_1_LEFT = 0x0001, - VEHICLE_SEAT_ROW_1_CENTER = 0x0002, - VEHICLE_SEAT_ROW_1_RIGHT = 0x0004, - VEHICLE_SEAT_ROW_2_LEFT = 0x0010, - VEHICLE_SEAT_ROW_2_CENTER = 0x0020, - VEHICLE_SEAT_ROW_2_RIGHT = 0x0040, - VEHICLE_SEAT_ROW_3_LEFT = 0x0100, - VEHICLE_SEAT_ROW_3_CENTER = 0x0200, - VEHICLE_SEAT_ROW_3_RIGHT = 0x0400 -}; - -/** - * Various windshields/windows in the car. - */ -enum vehicle_window { - VEHICLE_WINDOW_FRONT_WINDSHIELD = 0x0001, - VEHICLE_WINDOW_REAR_WINDSHIELD = 0x0002, - VEHICLE_WINDOW_ROOF_TOP = 0x0004, - VEHICLE_WINDOW_ROW_1_LEFT = 0x0010, - VEHICLE_WINDOW_ROW_1_RIGHT = 0x0020, - VEHICLE_WINDOW_ROW_2_LEFT = 0x0100, - VEHICLE_WINDOW_ROW_2_RIGHT = 0x0200, - VEHICLE_WINDOW_ROW_3_LEFT = 0x1000, - VEHICLE_WINDOW_ROW_3_RIGHT = 0x2000, -}; - -enum vehicle_door { - VEHICLE_DOOR_ROW_1_LEFT = 0x00000001, - VEHICLE_DOOR_ROW_1_RIGHT = 0x00000004, - VEHICLE_DOOR_ROW_2_LEFT = 0x00000010, - VEHICLE_DOOR_ROW_2_RIGHT = 0x00000040, - VEHICLE_DOOR_ROW_3_LEFT = 0x00000100, - VEHICLE_DOOR_ROW_3_RIGHT = 0x00000400, - VEHICLE_DOOR_HOOD = 0x10000000, - VEHICLE_DOOR_REAR = 0x20000000, -}; - -enum vehicle_mirror { - VEHICLE_MIRROR_DRIVER_LEFT = 0x00000001, - VEHICLE_MIRROR_DRIVER_RIGHT = 0x00000002, - VEHICLE_MIRROR_DRIVER_CENTER = 0x00000004, -}; - -enum vehicle_turn_signal { - VEHICLE_SIGNAL_NONE = 0x00, - VEHICLE_SIGNAL_RIGHT = 0x01, - VEHICLE_SIGNAL_LEFT = 0x02, - VEHICLE_SIGNAL_EMERGENCY = 0x04 -}; - -enum vehicle_zone_type { - VEHICLE_ZONE_TYPE_NONE = 0x00, - VEHICLE_ZONE_TYPE_ZONE = 0x01, - VEHICLE_ZONE_TYPE_SEAT = 0x02, - VEHICLE_ZONE_TYPE_DOOR = 0x04, - VEHICLE_ZONE_TYPE_WINDOW = 0x10, - VEHICLE_ZONE_TYPE_MIRROR = 0x20, -}; - -/* - * Boolean type. - */ -enum vehicle_boolean { - VEHICLE_FALSE = 0x00, - VEHICLE_TRUE = 0x01 -}; - -typedef int32_t vehicle_boolean_t; - -/** - * Vehicle string. - * - * Defines a UTF8 encoded sequence of bytes that should be used for string - * representation throughout. - */ -typedef struct vehicle_str { - uint8_t* data; - int32_t len; -} vehicle_str_t; - -/** - * Vehicle byte array. - * This is for passing generic raw data. - */ -typedef vehicle_str_t vehicle_bytes_t; - -typedef struct vehicle_prop_config { - int32_t prop; - - /** - * Defines if the property is read or write. Value should be one of - * enum vehicle_prop_access. - */ - int32_t access; - - /** - * Defines if the property is continuous or on-change. Value should be one - * of enum vehicle_prop_change_mode. - */ - int32_t change_mode; - - /** - * Type of data used for this property. This type is fixed per each property. - * Check vehicle_value_type for allowed value. - */ - int32_t value_type; - - /** - * Define necessary permission model to access the data. - */ - int32_t permission_model; - - /** - * Some of the properties may have associated zones (such as hvac), in these - * cases the config should contain an ORed value for the associated zone. - */ - union { - /** - * The value is derived by ORing one or more of enum vehicle_zone members. - */ - int32_t vehicle_zone_flags; - /** The value is derived by ORing one or more of enum vehicle_seat members. */ - int32_t vehicle_seat_flags; - /** The value is derived by ORing one or more of enum vehicle_window members. */ - int32_t vehicle_window_flags; - }; - - /** - * Property specific configuration information. Usage of this will be defined per each property. - */ - union { - /** - * For generic configuration information - */ - int32_t config_flags; - /** The number of presets that are stored by the radio module. Pass 0 if - * there are no presets available. The range of presets is defined to be - * from 1 (see VEHICLE_RADIO_PRESET_MIN_VALUE) to vehicle_radio_num_presets. - */ - int32_t vehicle_radio_num_presets; - int32_t config_array[4]; - }; - - /** - * Some properties may require additional information passed over this string. Most properties - * do not need to set this and in that case, config_string.data should be NULL and - * config_string.len should be 0. - */ - vehicle_str_t config_string; - - /** - * Specify minimum allowed value for the property. This is necessary for property which does - * not have specified enum. - */ - union { - float float_min_value; - int32_t int32_min_value; - int64_t int64_min_value; - }; - - /** - * Specify maximum allowed value for the property. This is necessary for property which does - * not have specified enum. - */ - union { - float float_max_value; - int32_t int32_max_value; - int64_t int64_max_value; - }; - - /** - * Array of min values for zoned properties. Zoned property can specify min / max value in two - * different ways: - * 1. All zones having the same min / max value: *_min/max_value should be set and this - * array should be set to NULL. - * 2. All zones having separate min / max value: *_min/max_values array should be populated - * and its length should be the same as number of active zones specified by *_zone_flags. - * - * Should be NULL if each zone does not have separate max values. - */ - union { - float* float_min_values; - int32_t* int32_min_values; - int64_t* int64_min_values; - }; - - /** - * Array of max values for zoned properties. See above for its usage. - * Should be NULL if each zone does not have separate max values. - * If not NULL, length of array should match that of min_values. - */ - union { - float* float_max_values; - int32_t* int32_max_values; - int64_t* int64_max_values; - }; - - /** - * Min sample rate in Hz. Should be 0 for sensor type of VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - */ - float min_sample_rate; - /** - * Max sample rate in Hz. Should be 0 for sensor type of VEHICLE_PROP_CHANGE_MODE_ON_CHANGE - */ - float max_sample_rate; - /** - * Place holder for putting HAL implementation specific data. Usage is wholly up to HAL - * implementation. - */ - void* hal_data; -} vehicle_prop_config_t; - -/** - * HVAC property fields. - * - * Defines various HVAC properties which are packed into vehicle_hvac_t (see - * below). We define these properties outside in global scope so that HAL - * implementation and HAL users (JNI) can typecast vehicle_hvac correctly. - */ -typedef struct vehicle_hvac { - /** - * Define one structure for each possible HVAC property. - * NOTES: - * a) Fan speed is a number from (0 - 6) where 6 is the highest speed. (TODO define enum) - * b) Temperature is a floating point Celcius scale. - * c) Direction is defined in enum vehicle_fan_direction. - * - * The HAL should create #entries number of vehicle_hvac_properties and - * assign it to "properties" variable below. - */ - union { - int32_t fan_speed; - int32_t fan_direction; - vehicle_boolean_t ac_on; - vehicle_boolean_t max_ac_on; - vehicle_boolean_t max_defrost_on; - vehicle_boolean_t recirc_on; - vehicle_boolean_t dual_on; - vehicle_boolean_t auto_on; - vehicle_boolean_t power_on; - - float temperature_current; - float temperature_set; - - vehicle_boolean_t defrost_on; - }; -} vehicle_hvac_t; - -/* - * Defines how the values for various properties are represented. - * - * There are two ways to populate and access the fields: - * a) Using the individual fields. Use this mechanism (see - * info_manufacture_date, fuel_capacity fields etc). - * b) Using the union accessors (see uint32_value, float_value etc). - * - * To add a new field make sure that it does not exceed the total union size - * (defined in int_array) and it is one of the vehicle_value_type. Then add the - * field name with its unit to union. If the field type is not yet defined (as - * of this draft, we don't use int64_t) then add that type to vehicle_value_type - * and have an accessor (so for int64_t it will be int64_t int64_value). - */ -typedef union vehicle_value { - /** Define the max size of this structure. */ - int32_t int32_array[4]; - float float_array[4]; - - // Easy accessors for union members (HAL implementation SHOULD NOT USE these - // fields while populating, use the property specific fields below instead). - int32_t int32_value; - int64_t int64_value; - float float_value; - vehicle_str_t str_value; - vehicle_bytes_t bytes_value; - vehicle_boolean_t boolean_value; - - // Vehicle Information. - vehicle_str_t info_vin; - vehicle_str_t info_make; - vehicle_str_t info_model; - int32_t info_model_year; - - // Represented in milliliters. - float info_fuel_capacity; - - float vehicle_speed; - float odometer; - - // Engine sensors. - - // Represented in milliliters. - //float engine_coolant_level; - // Represented in celcius. - float engine_coolant_temperature; - // Represented in a percentage value. - //float engine_oil_level; - // Represented in celcius. - float engine_oil_temperature; - float engine_rpm; - - // Event sensors. - // Value should be one of enum vehicle_gear_selection. - int32_t gear_selection; - // Value should be one of enum vehicle_gear. - int32_t gear_current_gear; - // Value should be one of enum vehicle_boolean. - int32_t parking_brake; - // If cruise_set_speed > 0 then cruise is ON otherwise cruise is OFF. - // Unit: meters / second (m/s). - //int32_t cruise_set_speed; - // Value should be one of enum vehicle_boolean. - int32_t is_fuel_level_low; - // Value should be one of enum vehicle_driving_status. - int32_t driving_status; - int32_t night_mode; - // Value should be one of emum vehicle_turn_signal. - int32_t turn_signals; - // Value should be one of enum vehicle_boolean. - //int32_t engine_on; - - // HVAC properties. - vehicle_hvac_t hvac; - - float outside_temperature; - float cabin_temperature; - -} vehicle_value_t; - -/* - * Encapsulates the property name and the associated value. It - * is used across various API calls to set values, get values or to register for - * events. - */ -typedef struct vehicle_prop_value { - /* property identifier */ - int32_t prop; - - /* value type of property for quick conversion from union to appropriate - * value. The value must be one of enum vehicle_value_type. - */ - int32_t value_type; - - /** time is elapsed nanoseconds since boot */ - int64_t timestamp; - - /** - * Zone information for zoned property. For non-zoned property, this should be ignored. - */ - union { - int32_t zone; - int32_t seat; - int32_t window; - }; - - vehicle_value_t value; -} vehicle_prop_value_t; - -/* - * Event callback happens whenever a variable that the API user has subscribed - * to needs to be reported. This may be based purely on threshold and frequency - * (a regular subscription, see subscribe call's arguments) or when the set() - * command is executed and the actual change needs to be reported. - * - * event_data is OWNED by the HAL and should be copied before the callback - * finishes. - */ -typedef int (*vehicle_event_callback_fn)(const vehicle_prop_value_t *event_data); - - -/** - * Represent the operation where the current error has happened. - */ -enum vehicle_property_operation { - /** Generic error to this property which is not tied to any operation. */ - VEHICLE_OPERATION_GENERIC = 0, - /** Error happened while handling property set. */ - VEHICLE_OPERATION_SET = 1, - /** Error happened while handling property get. */ - VEHICLE_OPERATION_GET = 2, - /** Error happened while handling property subscription. */ - VEHICLE_OPERATION_SUBSCRIBE = 3, -}; - -/* - * Suggests that an error condition has occurred. - * - * @param error_code Error code. error_code should be standard error code with - * negative value like -EINVAL. - * @parm property Note a property where error has happened. If this is generic error, property - * should be VEHICLE_PROPERTY_INVALID. - * @param operation Represent the operation where the error has happened. Should be one of - * vehicle_property_operation. - */ -typedef int (*vehicle_error_callback_fn)(int32_t error_code, int32_t property, int32_t operation); - -/************************************************************************************/ - -/* - * Every hardware module must have a data structure named HAL_MODULE_INFO_SYM - * and the fields of this data structure must begin with hw_module_t - * followed by module specific information. - */ -typedef struct vehicle_module { - struct hw_module_t common; -} vehicle_module_t; - - -typedef struct vehicle_hw_device { - struct hw_device_t common; - - /** - * After calling open on device the user should register callbacks for event and error - * functions. - */ - int (*init)(struct vehicle_hw_device* device, - vehicle_event_callback_fn event_fn, vehicle_error_callback_fn err_fn); - /** - * Before calling close the user should destroy the registered callback - * functions. - * In case the unsubscribe() call is not called on all properties before - * release() then release() will unsubscribe the properties itself. - */ - int (*release)(struct vehicle_hw_device* device); - - /** - * Enumerate all available properties. The list is returned in "list". - * @param num_properties number of properties contained in the retuned array. - * @return array of property configs supported by this car. Note that returned data is const - * and caller cannot modify it. HAL implementation should keep this memory until HAL - * is released to avoid copying this again. - */ - vehicle_prop_config_t const *(*list_properties)(struct vehicle_hw_device* device, - int* num_properties); - - /** - * Get a vehicle property value immediately. data should be allocated - * properly. - * The caller of the API OWNS the data field. - * Caller will set data->prop, data->value_type, and optionally zone value for zoned property. - * But HAL implementation needs to fill all entries properly when returning. - * For pointer type, HAL implementation should allocate necessary memory and caller is - * responsible for calling release_memory_from_get, which allows HAL to release allocated - * memory. - * For VEHICLE_PROP_CHANGE_MODE_STATIC type of property, get should return the same value - * always. - * For VEHICLE_PROP_CHANGE_MODE_ON_CHANGE type of property, it should return the latest value. - * If there is no data available yet, which can happen during initial stage, this call should - * return immediately with error code of -EAGAIN. - */ - int (*get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data); - - /** - * Release memory allocated to data in previous get call. get call for byte or string involves - * allocating necessary memory from vehicle hal. - * To be safe, memory allocated by vehicle hal should be released by vehicle hal and vehicle - * network service will call this when data from vehicle hal is no longer necessary. - * vehicle hal implementation should only release member of vehicle_prop_value_t like - * data->str_value.data or data->bytes_value.data but not data itself as data itself is - * allocated from vehicle network service. Once memory is freed, corresponding pointer should - * be set to NULL bu vehicle hal. - */ - void (*release_memory_from_get)(struct vehicle_hw_device* device, vehicle_prop_value_t *data); - - /** - * Set a vehicle property value. data should be allocated properly and not - * NULL. - * The caller of the API OWNS the data field. - * timestamp of data will be ignored for set operation. - * Setting some properties require having initial state available. Depending on the vehicle hal, - * such initial data may not be available for short time after init. In such case, set call - * can return -EAGAIN like get call. - * For a property with separate power control, set can fail if the property is not powered on. - * In such case, hal should return -ESHUTDOWN error. - */ - int (*set)(struct vehicle_hw_device* device, const vehicle_prop_value_t *data); - - /** - * Subscribe to events. - * Depending on output of list_properties if the property is: - * a) on-change: sample_rate should be set to 0. - * b) supports frequency: sample_rate should be set from min_sample_rate to - * max_sample_rate. - * For on-change type of properties, vehicle network service will make another get call to check - * the initial state. Due to this, vehicle hal implementation does not need to send initial - * state for on-change type of properties. - * @param device - * @param prop - * @param sample_rate - * @param zones All subscribed zones for zoned property. can be ignored for non-zoned property. - * 0 means all zones supported instead of no zone. - */ - int (*subscribe)(struct vehicle_hw_device* device, int32_t prop, float sample_rate, - int32_t zones); - - /** Cancel subscription on a property. */ - int (*unsubscribe)(struct vehicle_hw_device* device, int32_t prop); - - /** - * Print out debugging state for the vehicle hal. This will be called by - * the vehicle network service and will be included into the service' dump. - * - * The passed-in file descriptor can be used to write debugging text using - * dprintf() or write(). The text should be in ASCII encoding only. - * - * Performance requirements: - * - * This must be a non-blocking call. The HAL should return from this call - * in 1ms, must return from this call in 10ms. This call must avoid - * deadlocks, as it may be called at any point of operation. - * Any synchronization primitives used (such as mutex locks or semaphores) - * should be acquired with a timeout. - */ - int (*dump)(struct vehicle_hw_device* device, int fd); - -} vehicle_hw_device_t; - -__END_DECLS - -#endif // ANDROID_VEHICLE_INTERFACE_H diff --git a/modules/vehicle/Android.bp b/modules/vehicle/Android.bp deleted file mode 100644 index cb0406a9..00000000 --- a/modules/vehicle/Android.bp +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (C) 2012 The Android Open Source Project -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -cc_library_shared { - name: "vehicle.default", - - relative_install_path: "hw", - vendor: true, - srcs: [ - "vehicle.c", - "timeUtil.cpp", - ], - cflags: [ - "-Wall", - "-Werror", - ], - header_libs: ["libhardware_headers"], - shared_libs: [ - "liblog", - "libcutils", - "libutils", - ], -} diff --git a/modules/vehicle/timeUtil.cpp b/modules/vehicle/timeUtil.cpp deleted file mode 100644 index fb27dad6..00000000 --- a/modules/vehicle/timeUtil.cpp +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 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. - */ - -#include -#include - -extern "C" { - int64_t elapsedRealtimeNano() { - return android::elapsedRealtimeNano(); - } -} diff --git a/modules/vehicle/vehicle.c b/modules/vehicle/vehicle.c deleted file mode 100644 index 66a2137a..00000000 --- a/modules/vehicle/vehicle.c +++ /dev/null @@ -1,579 +0,0 @@ -/* - * Copyright (C) 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. - */ - -#define LOG_TAG "vehicle_hw_default" -#define LOG_NDEBUG 1 -#define RADIO_PRESET_NUM 6 - -#define UNUSED __attribute__((__unused__)) - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -extern int64_t elapsedRealtimeNano(); - -static char VEHICLE_MAKE[] = "android_car"; - -typedef struct vehicle_device_impl { - vehicle_hw_device_t vehicle_device; - uint32_t initialized_; - vehicle_event_callback_fn event_fn_; - vehicle_error_callback_fn error_fn_; -} vehicle_device_impl_t ; - -static pthread_mutex_t lock_; - -typedef struct subscription { - // Each subscription has it's own thread. - pthread_t thread_id; - int32_t prop; - float sample_rate; - pthread_mutex_t lock; - // This field should be protected by the above mutex. - // TODO change this to something better as flag alone takes long time to finish. - uint32_t stop_thread; - vehicle_device_impl_t* impl; - pthread_t thread; - pthread_cond_t cond; - char name[100]; -} subscription_t; - -static vehicle_prop_config_t CONFIGS[] = { - { - .prop = VEHICLE_PROPERTY_INFO_MAKE, - .access = VEHICLE_PROP_ACCESS_READ, - .change_mode = VEHICLE_PROP_CHANGE_MODE_STATIC, - .value_type = VEHICLE_VALUE_TYPE_STRING, - .min_sample_rate = 0, - .max_sample_rate = 0, - .hal_data = NULL, - }, - { - .prop = VEHICLE_PROPERTY_GEAR_SELECTION, - .access = VEHICLE_PROP_ACCESS_READ, - .change_mode = VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, - .value_type = VEHICLE_VALUE_TYPE_INT32, - .min_sample_rate = 0, - .max_sample_rate = 0, - .hal_data = NULL, - }, - { - .prop = VEHICLE_PROPERTY_DRIVING_STATUS, - .access = VEHICLE_PROP_ACCESS_READ, - .change_mode = VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, - .value_type = VEHICLE_VALUE_TYPE_INT32, - .min_sample_rate = 0, - .max_sample_rate = 0, - .hal_data = NULL, - }, - { - .prop = VEHICLE_PROPERTY_PARKING_BRAKE_ON, - .access = VEHICLE_PROP_ACCESS_READ, - .change_mode = VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, - .value_type = VEHICLE_VALUE_TYPE_BOOLEAN, - .min_sample_rate = 0, - .max_sample_rate = 0, - .hal_data = NULL, - }, - { - .prop = VEHICLE_PROPERTY_PERF_VEHICLE_SPEED, - .access = VEHICLE_PROP_ACCESS_READ, - .change_mode = VEHICLE_PROP_CHANGE_MODE_CONTINUOUS, - .value_type = VEHICLE_VALUE_TYPE_FLOAT, - .min_sample_rate = 0.1, - .max_sample_rate = 10.0, - .hal_data = NULL, - }, - { - .prop = VEHICLE_PROPERTY_RADIO_PRESET, - .access = VEHICLE_PROP_ACCESS_READ_WRITE, - .change_mode = VEHICLE_PROP_CHANGE_MODE_ON_CHANGE, - .value_type = VEHICLE_VALUE_TYPE_INT32_VEC4, - .vehicle_radio_num_presets = RADIO_PRESET_NUM, - .min_sample_rate = 0, - .max_sample_rate = 0, - .hal_data = NULL, - }, -}; - -vehicle_prop_config_t* find_config(int prop) { - unsigned int i; - for (i = 0; i < sizeof(CONFIGS) / sizeof(vehicle_prop_config_t); i++) { - if (CONFIGS[i].prop == prop) { - return &CONFIGS[i]; - } - } - return NULL; -} - -static int alloc_vehicle_str_from_cstr(const char* string, vehicle_str_t* vehicle_str) { - int len = strlen(string); - vehicle_str->data = (uint8_t*) malloc(len); - if (vehicle_str->data == NULL) { - return -ENOMEM; - } - memcpy(vehicle_str->data, string, len); - vehicle_str->len = len; - return 0; -} - -static vehicle_prop_config_t const * vdev_list_properties(vehicle_hw_device_t* device UNUSED, - int* num_properties) { - ALOGD("vdev_list_properties."); - - *num_properties = sizeof(CONFIGS) / sizeof(vehicle_prop_config_t); - return CONFIGS; -} - -static int vdev_init(vehicle_hw_device_t* device, - vehicle_event_callback_fn event_callback_fn, - vehicle_error_callback_fn error_callback_fn) { - ALOGD("vdev_init."); - vehicle_device_impl_t* impl = (vehicle_device_impl_t*)device; - pthread_mutex_lock(&lock_); - if (impl->initialized_) { - ALOGE("vdev_init: Callback and Error functions are already existing."); - pthread_mutex_unlock(&lock_); - return -EEXIST; - } - - impl->initialized_ = 1; - impl->event_fn_ = event_callback_fn; - impl->error_fn_ = error_callback_fn; - pthread_mutex_unlock(&lock_); - return 0; -} - -static int vdev_release(vehicle_hw_device_t* device) { - vehicle_device_impl_t* impl = (vehicle_device_impl_t*)device; - pthread_mutex_lock(&lock_); - if (!impl->initialized_) { - ALOGD("vdev_release: Already released before, returning early."); - } else { - // unsubscribe_all() - impl->initialized_ = 0; - } - pthread_mutex_unlock(&lock_); - return 0; -} - -static int vdev_get(vehicle_hw_device_t* device UNUSED, vehicle_prop_value_t* data) { - ALOGD("vdev_get."); - //TODO all data supporting read should support get - if (!data) { - ALOGE("vdev_get: Data cannot be null."); - return -EINVAL; - } - vehicle_prop_config_t* config = find_config(data->prop); - if (config == NULL) { - ALOGE("vdev_get: cannot find config 0x%x", data->prop); - return -EINVAL; - } - data->value_type = config->value_type; - // for STATIC type, time can be just 0 instead - data->timestamp = elapsedRealtimeNano(); - int r; - switch (data->prop) { - case VEHICLE_PROPERTY_INFO_MAKE: - r = alloc_vehicle_str_from_cstr(VEHICLE_MAKE, &(data->value.str_value)); - if (r != 0) { - ALOGE("vdev_get: alloc failed"); - return r; - } - break; - - case VEHICLE_PROPERTY_RADIO_PRESET: { - int radio_preset = data->value.int32_array[0]; - if (radio_preset < VEHICLE_RADIO_PRESET_MIN_VALUE || - radio_preset >= RADIO_PRESET_NUM) { - ALOGE("%s Invalid radio preset: %d\n", __func__, radio_preset); - return -1; - } - ALOGD("%s Radio Preset number: %d", __func__, radio_preset); - int32_t selector = radio_preset % 2 == 0; - // Populate the channel and subchannel to be some variation of the - // preset number for mocking. - - // Restore the preset number. - data->value.int32_array[0] = radio_preset; - // Channel type values taken from - // system/core/include/system/radio.h - data->value.int32_array[1] = selector ? RADIO_BAND_FM : RADIO_BAND_AM; - // For FM set a value in Mhz and for AM set a value in Khz range - // (channel). - data->value.int32_array[2] = selector ? 99000000 : 100000; - // For FM we have a sub-channel and we care about it, for AM pass - // a dummy value. - data->value.int32_array[3] = selector ? radio_preset : -1; - break; - } - - default: - // actual implementation will be much complex than this. It should track proper last - // state. Here just fill with zero. - memset(&(data->value), 0, sizeof(data->value)); - break; - } - ALOGI("vdev_get, type 0x%x, time %" PRId64 ", value_type %d", data->prop, data->timestamp, - data->value_type); - return 0; -} - -static void vdev_release_memory_from_get(struct vehicle_hw_device* device UNUSED, - vehicle_prop_value_t *data) { - switch (data->value_type) { - case VEHICLE_VALUE_TYPE_STRING: - case VEHICLE_VALUE_TYPE_BYTES: - free(data->value.str_value.data); - data->value.str_value.data = NULL; - break; - default: - ALOGW("release_memory_from_get for property 0x%x which is not string or bytes type 0x%x" - , data->prop, data->value_type); - break; - } -} - -static int vdev_set(vehicle_hw_device_t* device UNUSED, const vehicle_prop_value_t* data) { - ALOGD("vdev_set."); - // Just print what data will be setting here. - ALOGD("Setting property %d with value type %d\n", data->prop, data->value_type); - vehicle_prop_config_t* config = find_config(data->prop); - if (config == NULL) { - ALOGE("vdev_set: cannot find config 0x%x", data->prop); - return -EINVAL; - } - if (config->value_type != data->value_type) { - ALOGE("vdev_set: type mismatch, passed 0x%x expecting 0x%x", data->value_type, - config->value_type); - return -EINVAL; - } - switch (data->value_type) { - case VEHICLE_VALUE_TYPE_FLOAT: - ALOGD("Value type: FLOAT\nValue: %f\n", data->value.float_value); - break; - case VEHICLE_VALUE_TYPE_INT32: - ALOGD("Value type: INT32\nValue: %" PRId32 "\n", data->value.int32_value); - break; - case VEHICLE_VALUE_TYPE_INT64: - ALOGD("Value type: INT64\nValue: %" PRId64 "\n", data->value.int64_value); - break; - case VEHICLE_VALUE_TYPE_BOOLEAN: - ALOGD("Value type: BOOLEAN\nValue: %d\n", data->value.boolean_value); - break; - case VEHICLE_VALUE_TYPE_STRING: - ALOGD("Value type: STRING\n Size: %d\n", data->value.str_value.len); - // NOTE: We only handle ASCII strings here. - // Print the UTF-8 string. - char *ascii_out = (char *) malloc ((data->value.str_value.len + 1) * sizeof (char)); - memcpy(ascii_out, data->value.str_value.data, data->value.str_value.len); - ascii_out[data->value.str_value.len] = '\0'; - ALOGD("Value: %s\n", ascii_out); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC4: - ALOGD("Value type: INT32_VEC4\nValue[0]: %d Value[1] %d Value[2] %d Value[3] %d", - data->value.int32_array[0], data->value.int32_array[1], - data->value.int32_array[2], data->value.int32_array[3]); - break; - default: - ALOGD("Value type not yet handled: %d.\n", data->value_type); - } - return 0; -} - -void print_subscribe_info(vehicle_device_impl_t* impl UNUSED) { - unsigned int i; - for (i = 0; i < sizeof(CONFIGS) / sizeof(vehicle_prop_config_t); i++) { - subscription_t* sub = (subscription_t*)CONFIGS[i].hal_data; - if (sub != NULL) { - ALOGD("prop: %d rate: %f", sub->prop, sub->sample_rate); - } - } -} - -// This should be run in a separate thread always. -void fake_event_thread(struct subscription *sub) { - if (!sub) { - ALOGE("oops! subscription object cannot be NULL."); - exit(-1); - } - prctl(PR_SET_NAME, (unsigned long)sub->name, 0, 0, 0); - // Emit values in a loop, every 2 seconds. - while (1) { - // Create a random value depending on the property type. - vehicle_prop_value_t event; - event.prop = sub->prop; - event.timestamp = elapsedRealtimeNano(); - switch (sub->prop) { - case VEHICLE_PROPERTY_GEAR_SELECTION: - event.value_type = VEHICLE_VALUE_TYPE_INT32; - switch ((event.timestamp & 0x30000000)>>28) { - case 0: - event.value.gear_selection = VEHICLE_GEAR_PARK; - break; - case 1: - event.value.gear_selection = VEHICLE_GEAR_NEUTRAL; - break; - case 2: - event.value.gear_selection = VEHICLE_GEAR_DRIVE; - break; - case 3: - event.value.gear_selection = VEHICLE_GEAR_REVERSE; - break; - } - break; - case VEHICLE_PROPERTY_PARKING_BRAKE_ON: - event.value_type = VEHICLE_VALUE_TYPE_BOOLEAN; - if (event.timestamp & 0x20000000) { - event.value.parking_brake = VEHICLE_FALSE; - } else { - event.value.parking_brake = VEHICLE_TRUE; - } - break; - case VEHICLE_PROPERTY_PERF_VEHICLE_SPEED: - event.value_type = VEHICLE_VALUE_TYPE_FLOAT; - event.value.vehicle_speed = (float) ((event.timestamp & 0xff000000)>>24); - break; - case VEHICLE_PROPERTY_RADIO_PRESET: - event.value_type = VEHICLE_VALUE_TYPE_INT32_VEC4; - int presetInfo1[4] = {1 /* preset number */, 0 /* AM Band */, 1000, 0}; - int presetInfo2[4] = {2 /* preset number */, 1 /* FM Band */, 1000, 0}; - if (event.timestamp & 0x20000000) { - memcpy(event.value.int32_array, presetInfo1, sizeof(presetInfo1)); - } else { - memcpy(event.value.int32_array, presetInfo2, sizeof(presetInfo2)); - } - break; - default: // unsupported - if (sub->impl == NULL) { - ALOGE("subscription impl NULL"); - return; - } - if (sub->impl->error_fn_ != NULL) { - sub->impl->error_fn_(-EINVAL, VEHICLE_PROPERTY_INVALID, - VEHICLE_OPERATION_GENERIC); - } else { - ALOGE("Error function is null"); - } - ALOGE("Unsupported prop 0x%x, quit", sub->prop); - return; - } - if (sub->impl->event_fn_ != NULL) { - sub->impl->event_fn_(&event); - } else { - ALOGE("Event function is null"); - return; - } - pthread_mutex_lock(&sub->lock); - if (sub->stop_thread) { - ALOGD("exiting subscription request here."); - // Do any cleanup here. - pthread_mutex_unlock(&sub->lock); - return; - } - struct timespec now; - clock_gettime(CLOCK_REALTIME, &now); - now.tv_sec += 1; // sleep for one sec - pthread_cond_timedwait(&sub->cond, &sub->lock, &now); - pthread_mutex_unlock(&sub->lock); - } -} - -static int vdev_subscribe(vehicle_hw_device_t* device, int32_t prop, float sample_rate, - int32_t zones UNUSED) { - ALOGD("vdev_subscribe 0x%x, %f", prop, sample_rate); - vehicle_device_impl_t* impl = (vehicle_device_impl_t*)device; - // Check that the device is initialized. - pthread_mutex_lock(&lock_); - if (!impl->initialized_) { - pthread_mutex_unlock(&lock_); - ALOGE("vdev_subscribe: have you called init()?"); - return -EINVAL; - } - vehicle_prop_config_t* config = find_config(prop); - if (config == NULL) { - pthread_mutex_unlock(&lock_); - ALOGE("vdev_subscribe not supported property 0x%x", prop); - return -EINVAL; - } - if ((config->access != VEHICLE_PROP_ACCESS_READ) && - (config->access != VEHICLE_PROP_ACCESS_READ_WRITE)) { - pthread_mutex_unlock(&lock_); - ALOGE("vdev_subscribe read not supported on the property 0x%x", prop); - return -EINVAL; - } - if (config->change_mode == VEHICLE_PROP_CHANGE_MODE_STATIC) { - pthread_mutex_unlock(&lock_); - ALOGE("vdev_subscribe cannot subscribe static property 0x%x", prop); - return -EINVAL; - } - if ((config->change_mode == VEHICLE_PROP_CHANGE_MODE_ON_CHANGE) && (sample_rate != 0)) { - pthread_mutex_unlock(&lock_); - ALOGE("vdev_subscribe on change type should have 0 sample rate, property 0x%x, sample rate %f", - prop, sample_rate); - return -EINVAL; - } - if ((config->max_sample_rate < sample_rate) || (config->min_sample_rate > sample_rate)) { - - ALOGE("vdev_subscribe property 0x%x, invalid sample rate %f, min:%f, max:%f", - prop, sample_rate, config->min_sample_rate, config->max_sample_rate); - pthread_mutex_unlock(&lock_); - return -EINVAL; - } - subscription_t* sub = (subscription_t*)config->hal_data; - if (sub == NULL) { - sub = calloc(1, sizeof(subscription_t)); - sub->prop = prop; - sub->sample_rate = sample_rate; - sub->stop_thread = 0; - sub->impl = impl; - pthread_mutex_init(&sub->lock, NULL); - pthread_cond_init(&sub->cond, NULL); - config->hal_data = sub; - sprintf(sub->name, "vhal0x%x", prop); - } else if (sub->sample_rate != sample_rate){ // sample rate changed - //TODO notify this to fake sensor thread - sub->sample_rate = sample_rate; - pthread_mutex_unlock(&lock_); - return 0; - } - int ret_code = pthread_create( - &sub->thread, NULL, (void *(*)(void*))fake_event_thread, sub); - if (ret_code != 0) { - return -ret_code; - } - print_subscribe_info(impl); - pthread_mutex_unlock(&lock_); - return 0; -} - -static int vdev_unsubscribe(vehicle_hw_device_t* device, int32_t prop) { - ALOGD("vdev_unsubscribe 0x%x", prop); - vehicle_device_impl_t* impl = (vehicle_device_impl_t*)device; - pthread_mutex_lock(&lock_); - vehicle_prop_config_t* config = find_config(prop); - if (config == NULL) { - pthread_mutex_unlock(&lock_); - return -EINVAL; - } - subscription_t* sub = (subscription_t*)config->hal_data; - if (sub == NULL) { - pthread_mutex_unlock(&lock_); - return -EINVAL; - } - config->hal_data = NULL; - pthread_mutex_unlock(&lock_); - pthread_mutex_lock(&sub->lock); - sub->stop_thread = 1; - pthread_cond_signal(&sub->cond); - pthread_mutex_unlock(&sub->lock); - pthread_join(sub->thread, NULL); - pthread_cond_destroy(&sub->cond); - pthread_mutex_destroy(&sub->lock); - free(sub); - pthread_mutex_lock(&lock_); - print_subscribe_info(impl); - pthread_mutex_unlock(&lock_); - return 0; -} - -static int vdev_close(hw_device_t* device) { - vehicle_device_impl_t* impl = (vehicle_device_impl_t*)device; - if (impl) { - free(impl); - return 0; - } else { - return -1; - } -} - -static int vdev_dump(struct vehicle_hw_device* device UNUSED, int fd UNUSED) { - //TODO - return 0; -} - -/* - * The open function is provided as an interface in harwdare.h which fills in - * all the information about specific implementations and version specific - * informations in hw_device_t structure. After calling open() the client should - * use the hw_device_t to execute any Vehicle HAL device specific functions. - */ -static int vdev_open(const hw_module_t* module, const char* name UNUSED, - hw_device_t** device) { - ALOGD("vdev_open"); - - // Oops, out of memory! - vehicle_device_impl_t* vdev = calloc(1, sizeof(vehicle_device_impl_t)); - if (vdev == NULL) { - return -ENOMEM; - } - - // Common functions provided by harware.h to access module and device(s). - vdev->vehicle_device.common.tag = HARDWARE_DEVICE_TAG; - vdev->vehicle_device.common.version = VEHICLE_DEVICE_API_VERSION_1_0; - vdev->vehicle_device.common.module = (hw_module_t *) module; - vdev->vehicle_device.common.close = vdev_close; - - // Define the Vehicle HAL device specific functions. - vdev->vehicle_device.list_properties = vdev_list_properties; - vdev->vehicle_device.init = vdev_init; - vdev->vehicle_device.release = vdev_release; - vdev->vehicle_device.get = vdev_get; - vdev->vehicle_device.release_memory_from_get = vdev_release_memory_from_get; - vdev->vehicle_device.set = vdev_set; - vdev->vehicle_device.subscribe = vdev_subscribe; - vdev->vehicle_device.unsubscribe = vdev_unsubscribe; - vdev->vehicle_device.dump = vdev_dump; - - *device = (hw_device_t *) vdev; - return 0; -} - -static struct hw_module_methods_t hal_module_methods = { - .open = vdev_open, -}; - -/* - * This structure is mandatory to be implemented by each HAL implementation. It - * exposes the open method (see hw_module_methods_t above) which opens a device. - * The vehicle HAL is supposed to be used as a single device HAL hence all the - * functions should be implemented inside of the vehicle_hw_device_t struct (see - * the vehicle.h in include/ folder. - */ -vehicle_module_t HAL_MODULE_INFO_SYM = { - .common = { - .tag = HARDWARE_MODULE_TAG, - .module_api_version = VEHICLE_MODULE_API_VERSION_1_0, - .hal_api_version = HARDWARE_HAL_API_VERSION, - .id = VEHICLE_HARDWARE_MODULE_ID, - .name = "Default vehicle HW HAL", - .author = "", - .methods = &hal_module_methods, - }, -}; diff --git a/tests/vehicle/Android.bp b/tests/vehicle/Android.bp deleted file mode 100644 index cbe2a11d..00000000 --- a/tests/vehicle/Android.bp +++ /dev/null @@ -1,48 +0,0 @@ -// -// Copyright (C) 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. - -// Build native tests. -cc_test { - name: "vehicle_tests", - srcs: ["vehicle_tests.cpp"], - - shared_libs: [ - "liblog", - "libhardware", - ], - - cflags: [ - "-Wall", - "-Wextra", - "-Werror", - ], -} - -// Build HAL command line utility. -cc_binary { - name: "vehicle-hal-tool", - srcs: ["vehicle-hal-tool.c"], - cflags: [ - "-Wall", - "-Wno-unused-parameter", - "-Werror", - ], - - shared_libs: [ - "libcutils", - "libhardware", - "liblog", - ], -} diff --git a/tests/vehicle/README b/tests/vehicle/README deleted file mode 100644 index 42d2210b..00000000 --- a/tests/vehicle/README +++ /dev/null @@ -1,73 +0,0 @@ -What does this document tell? - -This document details how to use the vehicle service if you are implementhing -HAL. It lists the various places to look for code and how to build and test the -code on your own dev device. - -This code also provides a simple command line utility for the target to test the -vehicle HAL. - -What is the code? - -The code is split into folowing logical components: -a) hardware/libhardware/include/hardware/vehicle.h - this is the main HAL -interface that will be required to be implemented by the OEMs. It includes all -documentation necessary to understand what vehicle subsystems are exposed, -various units, capabilities and any other relevant details about the HAL design -itself. - -b) hardware/libhardware/modules/vehicle/vehicle.c -This is a reference implementation for the OEMs to have a peek into getting -started with a barebones structure. There are implementation for each of the -critical HAL functions such as, get(), set() and subscribe(). - -c) hardware/libhardware/tests/vehicle/vehicle_test.cpp & vehicle_test_fixtures.h -These are native tests that can be run on the target to validate basic -features of HAL implementation. Things such as loading of HAL and -basic functions are implemented (by check if the returned functions are not NULL -pointers) can be asserted. It also checks if the subscribe function is doing its -job by spitting out data at continuous intervals and printed on the stdout. - -d) hardware/libhardware/tests/vehicle/vehicle-hal-tool.c -This tool will provide you with a simple utility which can set commands to the -HAL such as: -i) Getting a property (and printing its value). -ii) Setting a property (and the HAL will take some setting action). -iii) Subscribe to a property (and the HAL should send you values at some certain -intevals). - -See the usage() function in vehicle-hal-tool.c for details on how to use the -binary. - -How to build and run? - -You can build everything by issuing the following from the top of directory. It -is assumed that you have done a first run of make from the top level so that -intermediates are generated. - -$ croot -$ mmm hardware/libhardware - -This will generate the following binaries that we care about: -i) out/target/product/XXX/vendor/lib/hw/vehicle.default.so -ii) out/target/product/XXX/data/nativetest/vehicle_tests -iii) out/target/product/XXX/system/bin/vehicle-hal-tool - -The location for the first shared library would be: -$ adb push out/target/product/XXX/vendor/lib/hw/vehicle.default.so -/vendor/lib/hw -You can also use 'adb sync' if you like, although this is the easiest least -hassle way of putting it in place. - -The second binary is a native test - which is nothing but an executable for the -target device. You can load it anywhere in your /data directory and run it as: -$ adb push out/target/product/XXX/data/nativetest/vehicle_tests -/data/tmp/vehicle_tests -$ adb shell -$ ./data/tmp/vehicle_tests -<...output should be spitted with passing tests for atleast the reference -implementation ...> - -The last binary is the command line tool, to push the binary on your target do: -$ adb push out/target/product/XXX/system/bin/vehicle-hal-tool -/data/tmp/vehicle-hal-tool diff --git a/tests/vehicle/vehicle-hal-tool.c b/tests/vehicle/vehicle-hal-tool.c deleted file mode 100644 index 94624d34..00000000 --- a/tests/vehicle/vehicle-hal-tool.c +++ /dev/null @@ -1,537 +0,0 @@ -/* - * Copyright (C) 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. - */ - -#define LOG_TAG "vehicle-hal-tool" - -#include -#include -#include -#include - -#include - -#include -#include - -void usage() { - printf("Usage: " - "./vehicle-hal-tool [-l] [-m -p -t [-v]]\n" - "-l - List properties\n" - "-m - Mode (cannot be used with -l). Accepted strings: get, set or sub.\n" - "-p - Property (only used with -m)\n" - "-t - Type (only used with -m)\n" - "-w - Wait time in seconds (only used with -m set to sub)\n" - "-v - Value to which vehicle_prop_value is set\n" - "Depending on the type pass the value:\n" - "Int: pass a quoted integer\n" - "Float: pass a quoted float\n" - "Int array: pass a quoted space delimited int array, eg: \"1 2 3 4\" for\n:" - "setting int32_array's all 4 elements (see VEHICLE_VALUE_TYPE_INT32_VEC4\n" - "String: pass a normal string\n\n" - "The configurations to use the tool are as follows:\n" - "List Properties\n" - "---------------\n" - "./vehicle-hal-tool -l \n" - "Lists the various properties defined in HAL implementation. Use this to check if " - "the HAL implementation is correctly set up and exposing the capabilities correctly.\n" - - "Get Properties\n" - "---------------\n" - "./vehicle-hal-tool -m get -p -t [-v ]\n" - "Example: ./vehicle-hal-tool -m get -p 1028 -t 3 # VEHICLE_PROPERTY_DRIVING_STATUS\n" - "./vehicle-hal-tool -m get -p 257 -t 1 # VEHICLE_PROPERTY_INFO_MAKE\n" - "./vehicle-hal-tool -m get -p 2049 -t 19 -v \"3 0 0 0\"\n" - " # VEHICLE_PROPERTY_RADIO_PRESET\n" - "with preset value set to 3.\n\n" - "Set properties\n" - "--------------\n" - "./vehicle-hal-tool -m set -p 10 -t 1 -v random_property\n" - "Set properties may not be applicable to most properties\n\n" - "Subscribe properties\n" - "--------------------\n" - "Subscribes to be notified about a property change (depending on whether\n" - "it is a on change property or a continuous property) for seconds provided\n" - "as -w paramter.\n" - "./vehicle-hal-tool -m sub -p 1028 -w 10\n" - ); -} - -void list_all_properties(vehicle_hw_device_t *device) { - int num_configs = -1; - const vehicle_prop_config_t *configs = device->list_properties(device, &num_configs); - if (num_configs < 0) { - printf("List configs error. %d", num_configs); - exit(1); - } - - printf("Listing configs\n--------------------\n"); - int i = 0; - for (i = 0; i < num_configs; i++) { - const vehicle_prop_config_t *config_temp = configs + i; - printf("Property ID: %d\n" - "Property config_flags: %d\n" - "Property change mode: %d\n" - "Property min sample rate: %f\n" - "Property max sample rate: %f\n", - config_temp->prop, config_temp->config_flags, config_temp->change_mode, - config_temp->min_sample_rate, config_temp->max_sample_rate); - } -} - -static void print_property(const vehicle_prop_value_t *data) { - switch (data->value_type) { - case VEHICLE_VALUE_TYPE_STRING: - printf("Value type: STRING\n Size: %d\n", data->value.str_value.len); - // This implementation only supports ASCII. - char *ascii_out = (char *) malloc((data->value.str_value.len + 1) * sizeof(char)); - memcpy(ascii_out, data->value.str_value.data, data->value.str_value.len); - ascii_out[data->value.str_value.len] = '\0'; - printf("Value Type: STRING %s\n", ascii_out); - free(ascii_out); - break; - case VEHICLE_VALUE_TYPE_BYTES: - printf("Value type: BYTES\n Size: %d", data->value.bytes_value.len); - for (int i = 0; i < data->value.bytes_value.len; i++) { - if ((i % 16) == 0) { - printf("\n %04X: ", i); - } - printf("%02X ", data->value.bytes_value.data[i]); - } - printf("\n"); - break; - case VEHICLE_VALUE_TYPE_BOOLEAN: - printf("Value type: BOOLEAN\nValue: %d\n", data->value.boolean_value); - break; - case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN: - printf("Value type: ZONED_BOOLEAN\nZone: %d\n", data->zone); - printf("Value: %d\n", data->value.boolean_value); - break; - case VEHICLE_VALUE_TYPE_INT64: - printf("Value type: INT64\nValue: %" PRId64 "\n", data->value.int64_value); - break; - case VEHICLE_VALUE_TYPE_FLOAT: - printf("Value type: FLOAT\nValue: %f\n", data->value.float_value); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC2: - printf("Value type: FLOAT_VEC2\nValue[0]: %f ", data->value.float_array[0]); - printf("Value[1]: %f\n", data->value.float_array[1]); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC3: - printf("Value type: FLOAT_VEC3\nValue[0]: %f ", data->value.float_array[0]); - printf("Value[1]: %f ", data->value.float_array[1]); - printf("Value[2]: %f\n", data->value.float_array[2]); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC4: - printf("Value type: FLOAT_VEC4\nValue[0]: %f ", data->value.float_array[0]); - printf("Value[1]: %f ", data->value.float_array[1]); - printf("Value[2]: %f ", data->value.float_array[2]); - printf("Value[3]: %f\n", data->value.float_array[3]); - break; - case VEHICLE_VALUE_TYPE_INT32: - printf("Value type: INT32\nValue: %d\n", data->value.int32_value); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC2: - printf("Value type: INT32_VEC2\nValue[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d\n", data->value.int32_array[1]); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC3: - printf("Value type: INT32_VEC3\nValue[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d ", data->value.int32_array[1]); - printf("Value[2]: %d\n", data->value.int32_array[2]); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC4: - printf("Value type: INT32_VEC4\nValue[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d ", data->value.int32_array[1]); - printf("Value[2]: %d ", data->value.int32_array[2]); - printf("Value[3]: %d\n", data->value.int32_array[3]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT: - printf("Value type: ZONED_FLOAT\nZone: %d ", data->zone); - printf("Value: %f\n", data->value.float_value); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2: - printf("Value type: ZONED_FLOAT_VEC2\nZone: %d ", data->zone); - printf("Value[0]: %f", data->value.float_array[0]); - printf("Value[1]: %f\n", data->value.float_array[1]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3: - printf("Value type: ZONED_FLOAT_VEC3\nZone: %d ", data->zone); - printf("Value[0]: %f ", data->value.float_array[0]); - printf("Value[1]: %f ", data->value.float_array[1]); - printf("Value[2]: %f\n", data->value.float_array[2]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: - printf("Value type: ZONED_FLOAT_VEC4\nZone: %d ", data->zone); - printf("Value[0]: %f ", data->value.float_array[0]); - printf("Value[1]: %f ", data->value.float_array[1]); - printf("Value[2]: %f ", data->value.float_array[2]); - printf("Value[3]: %f\n", data->value.float_array[3]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32: - printf("Value type: ZONED_INT32\nZone: %d ", data->zone); - printf("Value: %d\n", data->value.int32_value); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2: - printf("Value type: ZONED_INT32_VEC2\nZone: %d ", data->zone); - printf("Value[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d\n", data->value.int32_array[1]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3: - printf("Value type: ZONED_INT32_VEC3\nZone: %d ", data->zone); - printf("Value[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d ", data->value.int32_array[1]); - printf("Value[2]: %d\n", data->value.int32_array[2]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: - printf("Value type: ZONED_INT32_VEC4\nZone: %d ", data->zone); - printf("Value[0]: %d ", data->value.int32_array[0]); - printf("Value[1]: %d ", data->value.int32_array[1]); - printf("Value[2]: %d ", data->value.int32_array[2]); - printf("Value[3]: %d\n", data->value.int32_array[3]); - break; - default: - printf("Value type not yet handled: %d.\n", data->value_type); - } -} - -void get_property( - vehicle_hw_device_t *device, int32_t property, int32_t type, char *value_string) { - vehicle_prop_value_t *data = (vehicle_prop_value_t *) malloc (sizeof(vehicle_prop_value_t)); - - // Parse the string according to type. - if (value_string != NULL && strlen(value_string) > 0) { - switch (type) { - case VEHICLE_VALUE_TYPE_INT32: - sscanf(value_string, "%d", &(data->value.int32_value)); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC4: - { - int32_t vec[4]; - sscanf(value_string, "%d %d %d %d", &vec[0], &vec[1], &vec[2], &vec[3]); - memcpy(data->value.int32_array, vec, sizeof(vec)); - break; - } - default: - printf("%s Setting value type not supported: %d\n", __func__, type); - exit(1); - } - } - - data->prop = property; - int ret_code = device->get(device, data); - if (ret_code != 0) { - printf("Cannot get property: %d\n", ret_code); - exit(1); - } - - // We simply convert the data into the type mentioned by the result of the - // get call. - printf("Get output\n------------\n"); - print_property(data); - free(data); -} - -void set_property(vehicle_hw_device_t *device, - int32_t property, - int32_t type, - char *data) { - vehicle_prop_value_t vehicle_data; - vehicle_data.prop = property; - vehicle_data.value_type = type; - int32_t zone = 0; - float value = 0.0; - switch (type) { - case VEHICLE_VALUE_TYPE_STRING: - // TODO: Make the code generic to UTF8 characters. - vehicle_data.value.str_value.len = strlen(data); - vehicle_data.value.str_value.data = - (uint8_t *) malloc (strlen(data) * sizeof(uint8_t)); - memcpy(vehicle_data.value.str_value.data, data, strlen(data) + 1); - break; - case VEHICLE_VALUE_TYPE_BYTES: { - int len = strlen(data); - int numBytes = (len + 1) / 3; - uint8_t *buf = calloc(numBytes, sizeof(uint8_t)); - char *byte = strtok(data, " "); - for (int i = 0; byte != NULL && i < numBytes; i++) { - buf[i] = strtol(data, NULL, 16); - byte = strtok(NULL, " "); - } - vehicle_data.value.bytes_value.len = numBytes; - vehicle_data.value.bytes_value.data = buf; - } - break; - case VEHICLE_VALUE_TYPE_BOOLEAN: - vehicle_data.value.boolean_value = atoi(data); - break; - case VEHICLE_VALUE_TYPE_ZONED_BOOLEAN: - sscanf(data, "%d %d", &vehicle_data.zone, - &vehicle_data.value.boolean_value); - break; - case VEHICLE_VALUE_TYPE_INT64: - vehicle_data.value.int64_value = atoi(data); - break; - case VEHICLE_VALUE_TYPE_FLOAT: - vehicle_data.value.float_value = atof(data); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC2: - sscanf(data, "%f %f", &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1]); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC3: - sscanf(data, "%f %f %f", &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1], - &vehicle_data.value.float_array[2]); - break; - case VEHICLE_VALUE_TYPE_FLOAT_VEC4: - sscanf(data, "%f %f %f %f", &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1], - &vehicle_data.value.float_array[2], - &vehicle_data.value.float_array[3]); - break; - case VEHICLE_VALUE_TYPE_INT32: - vehicle_data.value.int32_value = atoi(data); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC2: - sscanf(data, "%d %d", &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1]); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC3: - sscanf(data, "%d %d %d", &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1], - &vehicle_data.value.int32_array[2]); - break; - case VEHICLE_VALUE_TYPE_INT32_VEC4: - sscanf(data, "%d %d %d %d", &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1], - &vehicle_data.value.int32_array[2], - &vehicle_data.value.int32_array[3]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT: - sscanf(data, "%d %f", &zone, &value); - vehicle_data.zone = zone; - vehicle_data.value.float_value = value; - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC2: - sscanf(data, "%d %f %f", &vehicle_data.zone, - &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC3: - sscanf(data, "%d %f %f %f", &vehicle_data.zone, - &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1], - &vehicle_data.value.float_array[2]); - break; - case VEHICLE_VALUE_TYPE_ZONED_FLOAT_VEC4: - sscanf(data, "%d %f %f %f %f", &vehicle_data.zone, - &vehicle_data.value.float_array[0], - &vehicle_data.value.float_array[1], - &vehicle_data.value.float_array[2], - &vehicle_data.value.float_array[3]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32: - sscanf(data, "%d %d", &vehicle_data.zone, - &vehicle_data.value.int32_value); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC2: - sscanf(data, "%d %d %d", &vehicle_data.zone, - &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC3: - sscanf(data, "%d %d %d %d", &vehicle_data.zone, - &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1], - &vehicle_data.value.int32_array[2]); - break; - case VEHICLE_VALUE_TYPE_ZONED_INT32_VEC4: - sscanf(data, "%d %d %d %d %d", &vehicle_data.zone, - &vehicle_data.value.int32_array[0], - &vehicle_data.value.int32_array[1], - &vehicle_data.value.int32_array[2], - &vehicle_data.value.int32_array[3]); - break; - default: - printf("set_property: Value type not yet handled: %d\n", type); - exit(1); - } - printf("Setting Property id: %d\n", vehicle_data.prop); - print_property(&vehicle_data); - - int ret_code = device->set(device, &vehicle_data); - if (ret_code != 0) { - printf("Cannot set property: %d\n", ret_code); - exit(1); - } -} - -int vehicle_event_callback(const vehicle_prop_value_t *event_data) { - // Print what we got. - printf("Got some value from callback property: %d\n", event_data->prop); - printf("Timestamp: %" PRId64 "\n", event_data->timestamp); - print_property(event_data); - return 0; -} - -int vehicle_error_callback(int32_t error_code, int32_t property, int32_t operation) { - // Print what we got. - printf("Error code obtained: %d\n", error_code); - return 0; -} - -void subscribe_to_property( - vehicle_hw_device_t *device, - int32_t prop, - float sample_rate, - uint32_t wait_in_seconds) { - // Init the device with a callback. - int ret_code = device->subscribe(device, prop, 0, 0); - if (ret_code != 0) { - printf("Could not subscribe: %d\n", ret_code); - exit(1); - } - - // Callbacks will happen on one of the threads created by the HAL hence we - // can simply sleep here and see the output. - sleep(wait_in_seconds); - - // Unsubscribe and uninit. - ret_code = device->unsubscribe(device, prop); - if (ret_code != 0) { - printf("Error unsubscribing the HAL, still continuining to uninit HAL ..."); - } -} - -int main(int argc, char* argv[]) { - // Open the vehicle module and just ask for the list of properties. - const hw_module_t *hw_module = NULL; - int ret_code = hw_get_module(VEHICLE_HARDWARE_MODULE_ID, &hw_module); - if (ret_code != 0) { - printf("Cannot open the hw module. Does the HAL exist? %d\n", ret_code); - return -1; - } - - vehicle_module_t *vehicle_module = (vehicle_module_t *)(hw_module); - hw_device_t *device = NULL; - ret_code = vehicle_module->common.methods->open(hw_module, NULL, &device); - if (!device) { - printf("Cannot open the hw device: %d\n", ret_code); - return -1; - } - vehicle_hw_device_t *vehicle_device = (vehicle_hw_device_t *) (device); - printf("HAL Loaded!\n"); - - vehicle_device->init(vehicle_device, vehicle_event_callback, vehicle_error_callback); - - // If this is a list properties command - we check for -l command. - int list_properties = 0; - // Type of the property (see #defines in vehicle.h). - int property = -1; - // Type of the value of the property (see enum vehicle_value_type). - int type = -1; - // Whether the mode is "get" or "set". - char mode[100] = ""; - // Actual value as a string representation (supports only PODs for now). - // TODO: Support structures and complex types in the tool. - char value[100] = ""; - // Wait time for the subscribe type of calls. - // We keep a default in case the user does not specify one. - int wait_time_in_sec = 10; - // Sample rate for subscribe type of calls. - // Default value is 0 for onchange type of properties. - int sample_rate = 0; - // Int array string which represents the vehicle_value_t in array of - // numbers. See vehicle_prop_value_t.value.int32_array. - char int_array_string[1000]; int_array_string[0] = '\0'; - - int opt; - while ((opt = getopt(argc, argv, "lm:p:t:v:w:s:")) != -1) { - switch (opt) { - case 'l': - list_properties = 1; - break; - case 'm': - strcpy(mode, optarg); - break; - case 'p': - property = atoi(optarg); - break; - case 't': - type = atoi(optarg); - break; - case 'v': - strcpy(value, optarg); - break; - case 'w': - wait_time_in_sec = atoi(optarg); - break; - case 's': - sample_rate = atoi(optarg); - break; - } - } - - // We should have atleast one of list properties or mode (for get or set). - if (!list_properties && - !(!strcmp(mode, "get") || !strcmp(mode, "set") || !strcmp(mode, "sub"))) { - usage(); - exit(1); - } - - if (list_properties) { - printf("Listing properties...\n"); - list_all_properties(vehicle_device); - } else if (!strcmp(mode, "get")) { - printf("Getting property ...\n"); - if (property == -1) { - printf("Use -p to pass a valid Property.\n"); - usage(); - exit(1); - } - - int32_t int_array_list[4]; - int count = -1; - if (strlen(int_array_string) > 0) { - count = sscanf(int_array_string, "%d%d%d%d", - &int_array_list[0], &int_array_list[1], &int_array_list[2], &int_array_list[3]); - } - - get_property(vehicle_device, property, type, value); - } else if (!strcmp(mode, "set")) { - printf("Setting property ...\n"); - if (property == -1 || type == -1) { - printf("Use -p to pass a valid Property and -t to pass a valid Type.\n"); - usage(); - exit(1); - } - set_property(vehicle_device, property, type, value); - } else if (!strcmp(mode, "sub")) { - printf("Subscribing property ...\n"); - if (property == -1 || wait_time_in_sec <= 0) { - printf("Use -p to pass a valid property and -w to pass a valid wait time(s)\n"); - usage(); - exit(1); - } - subscribe_to_property(vehicle_device, property, sample_rate, wait_time_in_sec); - } - - ret_code = vehicle_device->release(vehicle_device); - if (ret_code != 0) { - printf("Error uniniting HAL, exiting anyways."); - } - return 0; -} diff --git a/tests/vehicle/vehicle_test_fixtures.h b/tests/vehicle/vehicle_test_fixtures.h deleted file mode 100644 index a9572baf..00000000 --- a/tests/vehicle/vehicle_test_fixtures.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 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_HAL_VEHICLE_TEST_ -#define __ANDROID_HAL_VEHICLE_TEST_ - -#include -#include -#include - -namespace tests { - -static const uint64_t kVersion = HARDWARE_DEVICE_API_VERSION_2(1, 0, 1); - -class VehicleModule : public testing::Test { -public: - VehicleModule() : - vehicle_module_(NULL) {} - ~VehicleModule() {} -protected: - virtual void SetUp() { - const hw_module_t *hw_module = NULL; - ASSERT_EQ(0, hw_get_module(VEHICLE_HARDWARE_MODULE_ID, &hw_module)) - << "Can't get vehicle module"; - ASSERT_TRUE(NULL != hw_module) - << "hw_get_module didn't return a valid hardware module"; - - vehicle_module_ = reinterpret_cast(hw_module); - } - const vehicle_module_t* vehicle_module() { return vehicle_module_; } -private: - const vehicle_module_t* vehicle_module_; -}; - - -int VehicleEventCallback(const vehicle_prop_value_t* event_data) { - // Print what we got. - std::cout << "got some value from callback: " - << event_data->prop - << " uint32 value: " - << event_data->value.int32_value << "\n"; - return 0; -} - - int VehicleErrorCallback(int32_t /*error_code*/, int32_t /*property*/, int32_t /*operation*/) { - // Do nothing. - return 0; -} - -class VehicleDevice : public VehicleModule { -public: - VehicleDevice() : - vehicle_device_(NULL) {} - ~VehicleDevice() {} -protected: - virtual void SetUp() { - VehicleModule::SetUp(); - hw_device_t *device = NULL; - ASSERT_TRUE(NULL != vehicle_module()->common.methods->open) - << "Vehicle open() is unimplemented"; - ASSERT_EQ(0, vehicle_module()->common.methods->open( - (const hw_module_t*)vehicle_module(), NULL, &device)) - << "Can't open vehicle device"; - ASSERT_TRUE(NULL != device) - << "Vehicle open() returned a NULL device"; - ASSERT_EQ(kVersion, device->version) - << "Unsupported version"; - vehicle_device_ = reinterpret_cast(device); - } - vehicle_hw_device_t* vehicle_device() { return vehicle_device_; } - vehicle_event_callback_fn callback_fn() { - return VehicleEventCallback; - } - vehicle_error_callback_fn error_fn() { - return VehicleErrorCallback; - } - - private: - vehicle_hw_device_t* vehicle_device_; -}; - -} // namespace tests - -#endif // __ANDROID_HAL_VEHICLE_TEST_ diff --git a/tests/vehicle/vehicle_tests.cpp b/tests/vehicle/vehicle_tests.cpp deleted file mode 100644 index 4c155709..00000000 --- a/tests/vehicle/vehicle_tests.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (C) 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. - */ - -#include -#include "vehicle_test_fixtures.h" -#include "hardware/vehicle.h" - -namespace tests { - -// Check if list_properties command exists. -TEST_F(VehicleDevice, isThereListProperties) { - ASSERT_TRUE(NULL != vehicle_device()->list_properties) - << "list_properties() function is not implemented"; - std::cout << "Test succeeds.\n"; -} - -// HAL should provide atleast one property. The output of this command should be -// used to verify the vailidity of the function. -TEST_F(VehicleDevice, listPropertiesMoreThanOne) { - vehicle_prop_config_t const* config; - int num_configs = -1; - config = vehicle_device()->list_properties(vehicle_device(), &num_configs); - ASSERT_TRUE(num_configs > -1) << "list_properties() call failed."; - ASSERT_TRUE(num_configs > 0) << "list_properties() returned zero items."; - std::cout << "Number of properties reported: " << num_configs << "\n"; - for (int i = 0; i < num_configs; i++) { - // Print each of the properties. - const vehicle_prop_config_t& config_temp = config[i]; - std::cout << "Property ID: " << config_temp.prop << "\n"; - std::cout << "Property flags: " << config_temp.config_flags << "\n"; - std::cout << "Property change mode: " << config_temp.change_mode << "\n"; - std::cout << "Property min sample rate: " << config_temp.min_sample_rate << "\n"; - std::cout << "Property max sample rate: " << config_temp.max_sample_rate << "\n\n"; - } -} - -// Test get() command. -// The fields are hardcoded in the dummy implementation and here. -TEST_F(VehicleDevice, getDriveState) { - vehicle_prop_value_t data; - data.prop = VEHICLE_PROPERTY_DRIVING_STATUS; - // Set drive_state field to EINVAL so that we can check that its valid when - // it comes back. - data.value_type = -EINVAL; - data.value.driving_status = -EINVAL; - vehicle_device()->get(vehicle_device(), &data); - - // Check that retured values are not invalid. - ASSERT_NE(data.value_type, -EINVAL) << "Drive state value type should be integer."; - ASSERT_NE(data.value.driving_status, -EINVAL) << "Driving status should be positive."; - - std::cout << "Driving status value type: " << data.value_type << "\n" - << "Driving status: " << data.value.driving_status << "\n"; -} - -// Test the workflows for subscribe and init/release. -// Subscribe will return error before init() is called or after release() is -// called. -TEST_F(VehicleDevice, initTest) { - // Test that init on a new device works. When getting an instance, we are - // already calling 'open' on the device. - int ret_code = - vehicle_device()->init(vehicle_device(), callback_fn(), error_fn()); - ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code; - - // Trying to init again should return an error. - ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn()); - ASSERT_EQ(ret_code, -EEXIST) << "ret code: " << ret_code; - - // Uninit should always return 0. - ret_code = vehicle_device()->release(vehicle_device()); - ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code; - - // We should be able to init again. - ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn()); - ASSERT_EQ(ret_code, 0) << "ret code: " << ret_code; - - // Finally release. - ret_code = vehicle_device()->release(vehicle_device()); - ASSERT_EQ(ret_code, 0) << "ret_code: " << ret_code; -} - -// Test that subscribe works. -// We wait for 10 seconds while which the vehicle.c can post messages from -// within it's own thread. -TEST_F(VehicleDevice, subscribeTest) { - // If the device is not init subscribe should fail off the bat. - int ret_code = vehicle_device()->subscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS, - 0, 0); - ASSERT_EQ(ret_code, -EINVAL) << "Return code is: " << ret_code; - - // Let's init the device. - ret_code = vehicle_device()->init(vehicle_device(), callback_fn(), error_fn()); - ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code; - - // Subscribe should now go through. - ret_code = vehicle_device()->subscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS, 0, 0); - ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code; - - // We should start getting some messages thrown from the callback. Let's - // wait for 20 seconds before unsubscribing. - std::cout << "Sleeping for 20 seconds."; - sleep(20); - std::cout << "Waking from sleep."; - - // This property does not exist, so we should get -EINVAL. - ret_code = vehicle_device()->unsubscribe(vehicle_device(), VEHICLE_PROPERTY_INFO_VIN); - ASSERT_EQ(ret_code, -EINVAL) << "Return code is: " << ret_code; - - // This property exists, so we should get a success return code - also this - // will be a blocking call. - ret_code = vehicle_device()->unsubscribe(vehicle_device(), VEHICLE_PROPERTY_DRIVING_STATUS); - ASSERT_EQ(ret_code, 0) << "Return code is: " << ret_code; -} - -} // namespace tests From 680068e9f224b9f82ab85034ca16a14395799e0b Mon Sep 17 00:00:00 2001 From: Brian Young Date: Mon, 29 Jan 2018 23:59:49 +0000 Subject: [PATCH 32/50] Revert "Add "Unlocked device required" parameter to keys" This reverts commit dc9505de44c70e701cdf27c7f7d8d9de5217f4b6. Reason for revert: Build breakages on elfin, gce_x86_phone. Bug: 72679761 Bug: 67752510 Change-Id: I53d396632b7a23141b755e028342accf6625ca0b --- include/hardware/keymaster_defs.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 25a4faac..6e812f29 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -112,8 +112,6 @@ typedef enum { KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout * if device is still on-body (requires secure * on-body sensor. */ - KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 508, /* Require the device screen to be unlocked if the - * key is used. */ /* Application access control */ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Specified to indicate key is usable by all @@ -454,7 +452,6 @@ typedef enum { KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64, KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65, KM_ERROR_CANNOT_ATTEST_IDS = -66, - KM_ERROR_DEVICE_LOCKED = -71, KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, From 001e6f4650449d576657cb4d1085cbfd743ea9b7 Mon Sep 17 00:00:00 2001 From: John Muir Date: Fri, 19 Jan 2018 16:50:25 -0800 Subject: [PATCH 33/50] audio: Update default audio implementation. Allow the default audio implementation to use the sample rate and format provided by the application, but default to 16-bit stereo for both input and output. Also, default to 10ms output buffer and 20ms input buffer. Bug: 70692394 Test: Audio device and output stream created successfully with the default frame_count. Audio device reports 20ms for input buffer size. Audio input stream created successfully with defaults. Setup device with audio_policy_configuration_stub.xml; no failures for GTS tests: GtsGmscoreHostTestCases -t 'com.google.android.gts.audio.AudioHostTest' Change-Id: If496fc89f72f26266a7ed9b59acf88d1ca76e704 --- modules/audio/audio_hw.c | 149 ++++++++++++++++++++++++++++++++------- 1 file changed, 125 insertions(+), 24 deletions(-) diff --git a/modules/audio/audio_hw.c b/modules/audio/audio_hw.c index 8f73f118..041cd474 100644 --- a/modules/audio/audio_hw.c +++ b/modules/audio/audio_hw.c @@ -32,6 +32,15 @@ #include #include +#define STUB_DEFAULT_SAMPLE_RATE 48000 +#define STUB_DEFAULT_AUDIO_FORMAT AUDIO_FORMAT_PCM_16_BIT + +#define STUB_INPUT_BUFFER_MILLISECONDS 20 +#define STUB_INPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_IN_STEREO + +#define STUB_OUTPUT_BUFFER_MILLISECONDS 10 +#define STUB_OUTPUT_DEFAULT_CHANNEL_MASK AUDIO_CHANNEL_OUT_STEREO + struct stub_audio_device { struct audio_hw_device device; }; @@ -39,46 +48,71 @@ struct stub_audio_device { struct stub_stream_out { struct audio_stream_out stream; int64_t last_write_time_us; + uint32_t sample_rate; + audio_channel_mask_t channel_mask; + audio_format_t format; + size_t frame_count; }; struct stub_stream_in { struct audio_stream_in stream; int64_t last_read_time_us; + uint32_t sample_rate; + audio_channel_mask_t channel_mask; + audio_format_t format; + size_t frame_count; }; static uint32_t out_get_sample_rate(const struct audio_stream *stream) { - return 44100; + const struct stub_stream_out *out = (const struct stub_stream_out *)stream; + + ALOGV("out_get_sample_rate: %u", out->sample_rate); + return out->sample_rate; } static int out_set_sample_rate(struct audio_stream *stream, uint32_t rate) { - ALOGV("out_set_sample_rate: %d", 0); - return -ENOSYS; + struct stub_stream_out *out = (struct stub_stream_out *)stream; + + ALOGV("out_set_sample_rate: %d", rate); + out->sample_rate = rate; + return 0; } static size_t out_get_buffer_size(const struct audio_stream *stream) { - ALOGV("out_get_buffer_size: %d", 4096); - return 4096; + const struct stub_stream_out *out = (const struct stub_stream_out *)stream; + size_t buffer_size = out->frame_count * + audio_stream_out_frame_size(&out->stream); + + ALOGV("out_get_buffer_size: %zu", buffer_size); + return buffer_size; } static audio_channel_mask_t out_get_channels(const struct audio_stream *stream) { - ALOGV("out_get_channels"); - return AUDIO_CHANNEL_OUT_STEREO; + const struct stub_stream_out *out = (const struct stub_stream_out *)stream; + + ALOGV("out_get_channels: %x", out->channel_mask); + return out->channel_mask; } static audio_format_t out_get_format(const struct audio_stream *stream) { - ALOGV("out_get_format"); - return AUDIO_FORMAT_PCM_16_BIT; + const struct stub_stream_out *out = (const struct stub_stream_out *)stream; + + ALOGV("out_get_format: %d", out->format); + return out->format; } static int out_set_format(struct audio_stream *stream, audio_format_t format) { - ALOGV("out_set_format: %d",format); - return -ENOSYS; + struct stub_stream_out *out = (struct stub_stream_out *)stream; + + ALOGV("out_set_format: %d", format); + out->format = format; + return 0; } static int out_standby(struct audio_stream *stream) @@ -109,7 +143,7 @@ static char * out_get_parameters(const struct audio_stream *stream, const char * static uint32_t out_get_latency(const struct audio_stream_out *stream) { ALOGV("out_get_latency"); - return 0; + return STUB_OUTPUT_BUFFER_MILLISECONDS; } static int out_set_volume(struct audio_stream_out *stream, float left, @@ -182,36 +216,54 @@ static int out_get_next_write_timestamp(const struct audio_stream_out *stream, /** audio_stream_in implementation **/ static uint32_t in_get_sample_rate(const struct audio_stream *stream) { - ALOGV("in_get_sample_rate"); - return 8000; + const struct stub_stream_in *in = (const struct stub_stream_in *)stream; + + ALOGV("in_get_sample_rate: %u", in->sample_rate); + return in->sample_rate; } static int in_set_sample_rate(struct audio_stream *stream, uint32_t rate) { - ALOGV("in_set_sample_rate: %d", rate); - return -ENOSYS; + struct stub_stream_in *in = (struct stub_stream_in *)stream; + + ALOGV("in_set_sample_rate: %u", rate); + in->sample_rate = rate; + return 0; } static size_t in_get_buffer_size(const struct audio_stream *stream) { - ALOGV("in_get_buffer_size: %d", 320); - return 320; + const struct stub_stream_in *in = (const struct stub_stream_in *)stream; + size_t buffer_size = in->frame_count * + audio_stream_in_frame_size(&in->stream); + + ALOGV("in_get_buffer_size: %zu", buffer_size); + return buffer_size; } static audio_channel_mask_t in_get_channels(const struct audio_stream *stream) { - ALOGV("in_get_channels: %d", AUDIO_CHANNEL_IN_MONO); - return AUDIO_CHANNEL_IN_MONO; + const struct stub_stream_in *in = (const struct stub_stream_in *)stream; + + ALOGV("in_get_channels: %x", in->channel_mask); + return in->channel_mask; } static audio_format_t in_get_format(const struct audio_stream *stream) { - return AUDIO_FORMAT_PCM_16_BIT; + const struct stub_stream_in *in = (const struct stub_stream_in *)stream; + + ALOGV("in_get_format: %d", in->format); + return in->format; } static int in_set_format(struct audio_stream *stream, audio_format_t format) { - return -ENOSYS; + struct stub_stream_in *in = (struct stub_stream_in *)stream; + + ALOGV("in_set_format: %d", format); + in->format = format; + return 0; } static int in_standby(struct audio_stream *stream) @@ -290,6 +342,13 @@ static int in_remove_audio_effect(const struct audio_stream *stream, effect_hand return 0; } +static size_t samples_per_milliseconds(size_t milliseconds, + uint32_t sample_rate, + size_t channel_count) +{ + return milliseconds * sample_rate * channel_count / 1000; +} + static int adev_open_output_stream(struct audio_hw_device *dev, audio_io_handle_t handle, audio_devices_t devices, @@ -323,7 +382,22 @@ static int adev_open_output_stream(struct audio_hw_device *dev, out->stream.write = out_write; out->stream.get_render_position = out_get_render_position; out->stream.get_next_write_timestamp = out_get_next_write_timestamp; + out->sample_rate = config->sample_rate; + if (out->sample_rate == 0) + out->sample_rate = STUB_DEFAULT_SAMPLE_RATE; + out->channel_mask = config->channel_mask; + if (out->channel_mask == AUDIO_CHANNEL_NONE) + out->channel_mask = STUB_OUTPUT_DEFAULT_CHANNEL_MASK; + out->format = config->format; + if (out->format == AUDIO_FORMAT_DEFAULT) + out->format = STUB_DEFAULT_AUDIO_FORMAT; + out->frame_count = samples_per_milliseconds( + STUB_OUTPUT_BUFFER_MILLISECONDS, + out->sample_rate, 1); + ALOGV("adev_open_output_stream: sample_rate: %u, channels: %x, format: %d," + " frames: %zu", out->sample_rate, out->channel_mask, out->format, + out->frame_count); *stream_out = &out->stream; return 0; } @@ -405,8 +479,21 @@ static int adev_get_mic_mute(const struct audio_hw_device *dev, bool *state) static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, const struct audio_config *config) { - ALOGV("adev_get_input_buffer_size: %d", 320); - return 320; + size_t buffer_size = samples_per_milliseconds( + STUB_INPUT_BUFFER_MILLISECONDS, + config->sample_rate, + audio_channel_count_from_in_mask( + config->channel_mask)); + + if (!audio_has_proportional_frames(config->format)) { + // Since the audio data is not proportional choose an arbitrary size for + // the buffer. + buffer_size *= 4; + } else { + buffer_size *= audio_bytes_per_sample(config->format); + } + ALOGV("adev_get_input_buffer_size: %zu", buffer_size); + return buffer_size; } static int adev_open_input_stream(struct audio_hw_device *dev, @@ -440,7 +527,21 @@ static int adev_open_input_stream(struct audio_hw_device *dev, in->stream.set_gain = in_set_gain; in->stream.read = in_read; in->stream.get_input_frames_lost = in_get_input_frames_lost; + in->sample_rate = config->sample_rate; + if (in->sample_rate == 0) + in->sample_rate = STUB_DEFAULT_SAMPLE_RATE; + in->channel_mask = config->channel_mask; + if (in->channel_mask == AUDIO_CHANNEL_NONE) + in->channel_mask = STUB_INPUT_DEFAULT_CHANNEL_MASK; + in->format = config->format; + if (in->format == AUDIO_FORMAT_DEFAULT) + in->format = STUB_DEFAULT_AUDIO_FORMAT; + in->frame_count = samples_per_milliseconds( + STUB_INPUT_BUFFER_MILLISECONDS, in->sample_rate, 1); + ALOGV("adev_open_input_stream: sample_rate: %u, channels: %x, format: %d," + "frames: %zu", in->sample_rate, in->channel_mask, in->format, + in->frame_count); *stream_in = &in->stream; return 0; } From 8a6fed0d280014d84fe0f6a802f1cf29600e5bae Mon Sep 17 00:00:00 2001 From: Eino-Ville Talvala Date: Mon, 5 Feb 2018 16:29:09 -0800 Subject: [PATCH 34/50] Camera: Revise MOTION_TRACKING capability Simplify the API for the P release. Test: Revised Camera CTS passes Bug: 63629224 Change-Id: Ib8379f928dbdb6c66850d7648ac814fe710bb104 --- include/hardware/camera3.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/include/hardware/camera3.h b/include/hardware/camera3.h index a58b8b4f..c3ea0aa7 100644 --- a/include/hardware/camera3.h +++ b/include/hardware/camera3.h @@ -183,7 +183,6 @@ * for a logical multi camera, the application has the option to specify individual * settings for a particular physical device. * - * - Add request templates MOTION_TRACKING_PREVIEW and MOTION_TRACKING_BEST */ /** @@ -2182,10 +2181,6 @@ typedef enum camera3_request_template { */ CAMERA3_TEMPLATE_MANUAL = 6, - // Added in 3.5 - CAMERA3_TEMPLATE_MOTION_TRACKING_PREVIEW = 7, - CAMERA3_TEMPLATE_MOTION_TRACKING_BEST = 8, - /* Total number of templates */ CAMERA3_TEMPLATE_COUNT, From 4028ac9ae6f56dbd9ee0baab5b76a40ffcb740a5 Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Mon, 12 Feb 2018 13:14:52 -0800 Subject: [PATCH 35/50] Fix a memory leak If status < 0, we'd silently leak dev. Bug: None Test: Ran the analyzer; memory leak warnings are gone. Change-Id: I76a78feea4c92aa167de908f5571481864d61d73 --- modules/gralloc/framebuffer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/gralloc/framebuffer.cpp b/modules/gralloc/framebuffer.cpp index 97964572..c1717115 100644 --- a/modules/gralloc/framebuffer.cpp +++ b/modules/gralloc/framebuffer.cpp @@ -332,6 +332,8 @@ int fb_device_open(hw_module_t const* module, const char* name, const_cast(dev->device.minSwapInterval) = 1; const_cast(dev->device.maxSwapInterval) = 1; *device = &dev->device.common; + } else { + free(dev); } } return status; From a684cb6c2cee0835065b123e4bb698487de26939 Mon Sep 17 00:00:00 2001 From: "Brian C. Young" Date: Thu, 16 Nov 2017 15:45:19 -0800 Subject: [PATCH 36/50] Restore "Add "Unlocked device required" parameter to keys" Add a keymaster parameter for keys that should be inaccessible when the device screen is locked. "Locked" here is a state where the device can be used or accessed without any further trust factor such as a PIN, password, fingerprint, or trusted face or voice. This parameter is added to the Java keystore interface for key creation and import, as well as enums specified by and for the native keystore process. This reverts commit 680068e9f224b9f82ab85034ca16a14395799e0b. Test: CTS tests in I8a5affd1eaed176756175158e3057e44934fffed Bug: 67752510 Change-Id: I9f3ea694f676801dc3dd348301544a603574edc7 --- include/hardware/keymaster_defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 6e812f29..25a4faac 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -112,6 +112,8 @@ typedef enum { KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout * if device is still on-body (requires secure * on-body sensor. */ + KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 508, /* Require the device screen to be unlocked if the + * key is used. */ /* Application access control */ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Specified to indicate key is usable by all @@ -452,6 +454,7 @@ typedef enum { KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64, KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65, KM_ERROR_CANNOT_ATTEST_IDS = -66, + KM_ERROR_DEVICE_LOCKED = -71, KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, From 80179932c94b9efa742e9f3237814611f72b8413 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 15 Feb 2018 17:07:19 -0800 Subject: [PATCH 37/50] r_submix: Add some tests Add simple tests to verify remote submix behavior regarding blocking writes. Currently one of the tests fails (does not finish), this needs to be fixed. Also fixed some minor issues in remote submix module code. Bug: 73175392 Test: r_submix_tests Change-Id: Ic88d0c385c0102e35b4f751f9c5cd8a6488949c8 --- modules/audio_remote_submix/audio_hw.cpp | 23 ++- modules/audio_remote_submix/tests/Android.bp | 29 ++++ .../tests/remote_submix_tests.cpp | 147 ++++++++++++++++++ 3 files changed, 187 insertions(+), 12 deletions(-) create mode 100644 modules/audio_remote_submix/tests/Android.bp create mode 100644 modules/audio_remote_submix/tests/remote_submix_tests.cpp diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index eb6ae929..8c0c0971 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -52,9 +52,9 @@ extern "C" { namespace android { -// Set to 1 to enable extremely verbose logging in this module. -#define SUBMIX_VERBOSE_LOGGING 0 -#if SUBMIX_VERBOSE_LOGGING +// Uncomment to enable extremely verbose logging in this module. +// #define SUBMIX_VERBOSE_LOGGING +#if defined(SUBMIX_VERBOSE_LOGGING) #define SUBMIX_ALOGV(...) ALOGV(__VA_ARGS__) #define SUBMIX_ALOGE(...) ALOGE(__VA_ARGS__) #else @@ -205,7 +205,7 @@ struct submix_stream_in { int log_fd; #endif // LOG_STREAMS_TO_FILES - volatile int16_t read_error_count; + volatile uint16_t read_error_count; }; // Determine whether the specified sample rate is supported by the submix module. @@ -467,11 +467,9 @@ static void submix_audio_device_release_pipe_l(struct submix_audio_device * cons rsxadev->routes[route_idx].address); if (rsxadev->routes[route_idx].rsxSink != 0) { rsxadev->routes[route_idx].rsxSink.clear(); - rsxadev->routes[route_idx].rsxSink = 0; } if (rsxadev->routes[route_idx].rsxSource != 0) { rsxadev->routes[route_idx].rsxSource.clear(); - rsxadev->routes[route_idx].rsxSource = 0; } memset(rsxadev->routes[route_idx].address, 0, AUDIO_DEVICE_MAX_ADDRESS_LEN); #ifdef ENABLE_RESAMPLING @@ -816,8 +814,8 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, static uint8_t flush_buffer[64]; const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size; size_t frames_to_flush_from_source = frames - availableToWrite; - SUBMIX_ALOGV("out_write(): flushing %d frames from the pipe to avoid blocking", - frames_to_flush_from_source); + SUBMIX_ALOGV("out_write(): flushing %llu frames from the pipe to avoid blocking", + (unsigned long long)frames_to_flush_from_source); while (frames_to_flush_from_source) { const size_t flush_size = min(frames_to_flush_from_source, flushBufferSizeFrames); frames_to_flush_from_source -= flush_size; @@ -898,7 +896,8 @@ static int out_get_presentation_position(const struct audio_stream_out *stream, } SUBMIX_ALOGV("out_get_presentation_position() got frames=%llu timestamp sec=%llu", - frames ? *frames : -1, timestamp ? timestamp->tv_sec : -1); + frames ? (unsigned long long)*frames : -1ULL, + timestamp ? (unsigned long long)timestamp->tv_sec : -1ULL); return ret; } @@ -1541,7 +1540,7 @@ static size_t adev_get_input_buffer_size(const struct audio_hw_device *dev, audio_bytes_per_sample(config->format); const size_t buffer_size = max_buffer_period_size_frames * frame_size_in_bytes; SUBMIX_ALOGV("adev_get_input_buffer_size() returns %zu bytes, %zu frames", - buffer_size, buffer_period_size_frames); + buffer_size, max_buffer_period_size_frames); return buffer_size; } return 0; @@ -1692,10 +1691,10 @@ static int adev_dump(const audio_hw_device_t *device, int fd) reinterpret_cast(device) - offsetof(struct submix_audio_device, device)); char msg[100]; - int n = sprintf(msg, "\nReroute submix audio module:\n"); + int n = snprintf(msg, sizeof(msg), "\nReroute submix audio module:\n"); write(fd, &msg, n); for (int i=0 ; i < MAX_ROUTES ; i++) { - n = sprintf(msg, " route[%d] rate in=%d out=%d, addr=[%s]\n", i, + n = snprintf(msg, sizeof(msg), " route[%d] rate in=%d out=%d, addr=[%s]\n", i, rsxadev->routes[i].config.input_sample_rate, rsxadev->routes[i].config.output_sample_rate, rsxadev->routes[i].address); diff --git a/modules/audio_remote_submix/tests/Android.bp b/modules/audio_remote_submix/tests/Android.bp new file mode 100644 index 00000000..8e4d42d0 --- /dev/null +++ b/modules/audio_remote_submix/tests/Android.bp @@ -0,0 +1,29 @@ +// Copyright (C) 2018 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. + +cc_test { + name: "r_submix_tests", + + srcs: ["remote_submix_tests.cpp"], + + shared_libs: [ + "libhardware", + "liblog", + "libutils", + ], + + cflags: ["-Wall", "-Werror", "-O0", "-g",], + + header_libs: ["libaudiohal_headers"], +} diff --git a/modules/audio_remote_submix/tests/remote_submix_tests.cpp b/modules/audio_remote_submix/tests/remote_submix_tests.cpp new file mode 100644 index 00000000..e644fd48 --- /dev/null +++ b/modules/audio_remote_submix/tests/remote_submix_tests.cpp @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2018 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. + */ + +// To run this test (as root): +// 1) Build it +// 2) adb push to /vendor/bin +// 3) adb shell /vendor/bin/r_submix_tests + +#define LOG_TAG "RemoteSubmixTest" + +#include + +#include +#include +#include +#include + +using namespace android; + +static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev) +{ + const hw_module_t *mod; + int rc; + + rc = hw_get_module_by_class(AUDIO_HARDWARE_MODULE_ID, if_name, &mod); + if (rc) { + ALOGE("%s couldn't load audio hw module %s.%s (%s)", __func__, + AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc)); + goto out; + } + rc = audio_hw_device_open(mod, dev); + if (rc) { + ALOGE("%s couldn't open audio hw device in %s.%s (%s)", __func__, + AUDIO_HARDWARE_MODULE_ID, if_name, strerror(-rc)); + goto out; + } + if ((*dev)->common.version < AUDIO_DEVICE_API_VERSION_MIN) { + ALOGE("%s wrong audio hw device version %04x", __func__, (*dev)->common.version); + rc = BAD_VALUE; + audio_hw_device_close(*dev); + goto out; + } + return OK; + +out: + *dev = NULL; + return rc; +} + +class RemoteSubmixTest : public testing::Test { + protected: + void SetUp() override; + void TearDown() override; + + void OpenInputStream(const char *address, audio_stream_in_t** streamIn); + void OpenOutputStream(const char *address, audio_stream_out_t** streamOut); + void WriteIntoStream(audio_stream_out_t* streamOut, size_t bufferSize, size_t repeats); + + audio_hw_device_t* mDev; +}; + +void RemoteSubmixTest::SetUp() { + mDev = nullptr; + ASSERT_EQ(OK, load_audio_interface(AUDIO_HARDWARE_MODULE_ID_REMOTE_SUBMIX, &mDev)); + ASSERT_NE(nullptr, mDev); +} + +void RemoteSubmixTest::TearDown() { + if (mDev != nullptr) { + int status = audio_hw_device_close(mDev); + mDev = nullptr; + ALOGE_IF(status, "Error closing audio hw device %p: %s", mDev, strerror(-status)); + ASSERT_EQ(0, status); + } +} + +void RemoteSubmixTest::OpenInputStream(const char *address, audio_stream_in_t** streamIn) { + *streamIn = nullptr; + struct audio_config configIn = {}; + configIn.channel_mask = AUDIO_CHANNEL_IN_MONO; + configIn.sample_rate = 48000; + status_t result = mDev->open_input_stream(mDev, + AUDIO_IO_HANDLE_NONE, AUDIO_DEVICE_NONE, &configIn, + streamIn, AUDIO_INPUT_FLAG_NONE, address, AUDIO_SOURCE_DEFAULT); + ASSERT_EQ(OK, result); + ASSERT_NE(nullptr, *streamIn); +} + +void RemoteSubmixTest::OpenOutputStream(const char *address, audio_stream_out_t** streamOut) { + *streamOut = nullptr; + struct audio_config configOut = {}; + configOut.channel_mask = AUDIO_CHANNEL_OUT_MONO; + configOut.sample_rate = 48000; + status_t result = mDev->open_output_stream(mDev, + AUDIO_IO_HANDLE_NONE, AUDIO_DEVICE_NONE, AUDIO_OUTPUT_FLAG_NONE, + &configOut, streamOut, address); + ASSERT_EQ(OK, result); + ASSERT_NE(nullptr, *streamOut); +} + +void RemoteSubmixTest::WriteIntoStream( + audio_stream_out_t* streamOut, size_t bufferSize, size_t repeats) { + std::unique_ptr buffer(new char[bufferSize]); + for (size_t i = 0; i < repeats; ++i) { + ssize_t result = streamOut->write(streamOut, buffer.get(), bufferSize); + EXPECT_EQ(bufferSize, static_cast(result)); + } +} + +TEST_F(RemoteSubmixTest, InitSuccess) { + // SetUp must finish with no assertions. +} + +// Verifies that when no input was opened, writing into an output stream does not block. +TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenNoInput) { + const char *address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, &streamOut); + WriteIntoStream(streamOut, 1024, 16); + mDev->close_output_stream(mDev, streamOut); +} + +// Verifies that when input is opened but not reading, writing into an output stream does not block. +// !!! Currently does not finish because requires setting a parameter from another thread !!! +TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { + const char *address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, &streamIn); + WriteIntoStream(streamOut, 1024, 16); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); +} From 968f997468f1fcb5c68157a850c8d5c79576c00c Mon Sep 17 00:00:00 2001 From: Brian Young Date: Thu, 22 Feb 2018 23:36:19 +0000 Subject: [PATCH 38/50] Revert "Restore "Add "Unlocked device required" parameter to keys"" This reverts commit a684cb6c2cee0835065b123e4bb698487de26939. Reason for revert: Regression in creating auth-bound keys Bug: 73773914 Bug: 67752510 Change-Id: Ib215d63efe442916f90065015a57614b097cd74d --- include/hardware/keymaster_defs.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 25a4faac..6e812f29 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -112,8 +112,6 @@ typedef enum { KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout * if device is still on-body (requires secure * on-body sensor. */ - KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 508, /* Require the device screen to be unlocked if the - * key is used. */ /* Application access control */ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Specified to indicate key is usable by all @@ -454,7 +452,6 @@ typedef enum { KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64, KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65, KM_ERROR_CANNOT_ATTEST_IDS = -66, - KM_ERROR_DEVICE_LOCKED = -71, KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, From bf115538e81820caf5c19df3ca13e5263eb1a1f8 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 27 Feb 2018 10:01:28 -0800 Subject: [PATCH 39/50] r_submix: Add more tests From analyzing the coverage data, these tests seem to cover all the critical functionality of the remote submix module. Bug: 73175392 Test: r_submix_tests Change-Id: I7f6be95245c6ab59611fc5e269e3f9f2079b8ee4 --- .../tests/remote_submix_tests.cpp | 225 ++++++++++++++++-- 1 file changed, 205 insertions(+), 20 deletions(-) diff --git a/modules/audio_remote_submix/tests/remote_submix_tests.cpp b/modules/audio_remote_submix/tests/remote_submix_tests.cpp index e644fd48..2c01c921 100644 --- a/modules/audio_remote_submix/tests/remote_submix_tests.cpp +++ b/modules/audio_remote_submix/tests/remote_submix_tests.cpp @@ -30,7 +30,7 @@ using namespace android; -static status_t load_audio_interface(const char *if_name, audio_hw_device_t **dev) +static status_t load_audio_interface(const char* if_name, audio_hw_device_t **dev) { const hw_module_t *mod; int rc; @@ -65,9 +65,19 @@ class RemoteSubmixTest : public testing::Test { void SetUp() override; void TearDown() override; - void OpenInputStream(const char *address, audio_stream_in_t** streamIn); - void OpenOutputStream(const char *address, audio_stream_out_t** streamOut); - void WriteIntoStream(audio_stream_out_t* streamOut, size_t bufferSize, size_t repeats); + void GenerateData(char* buffer, size_t bufferSize); + void OpenInputStream( + const char* address, bool mono, uint32_t sampleRate, audio_stream_in_t** streamIn); + void OpenOutputStream( + const char* address, bool mono, uint32_t sampleRate, audio_stream_out_t** streamOut); + void ReadFromStream(audio_stream_in_t* streamIn, char* buffer, size_t bufferSize); + void VerifyBufferAllZeroes(char* buffer, size_t bufferSize); + void VerifyBufferNotZeroes(char* buffer, size_t bufferSize); + void VerifyOutputInput( + audio_stream_out_t* streamOut, size_t outBufferSize, + audio_stream_in_t* streamIn, size_t inBufferSize, size_t repeats); + void WriteIntoStream(audio_stream_out_t* streamOut, const char* buffer, size_t bufferSize); + void WriteSomethingIntoStream(audio_stream_out_t* streamOut, size_t bufferSize, size_t repeats); audio_hw_device_t* mDev; }; @@ -87,11 +97,18 @@ void RemoteSubmixTest::TearDown() { } } -void RemoteSubmixTest::OpenInputStream(const char *address, audio_stream_in_t** streamIn) { +void RemoteSubmixTest::GenerateData(char* buffer, size_t bufferSize) { + for (size_t i = 0; i < bufferSize; ++i) { + buffer[i] = static_cast(i & 0x7f); + } +} + +void RemoteSubmixTest::OpenInputStream( + const char* address, bool mono, uint32_t sampleRate, audio_stream_in_t** streamIn) { *streamIn = nullptr; struct audio_config configIn = {}; - configIn.channel_mask = AUDIO_CHANNEL_IN_MONO; - configIn.sample_rate = 48000; + configIn.channel_mask = mono ? AUDIO_CHANNEL_IN_MONO : AUDIO_CHANNEL_IN_STEREO; + configIn.sample_rate = sampleRate; status_t result = mDev->open_input_stream(mDev, AUDIO_IO_HANDLE_NONE, AUDIO_DEVICE_NONE, &configIn, streamIn, AUDIO_INPUT_FLAG_NONE, address, AUDIO_SOURCE_DEFAULT); @@ -99,11 +116,12 @@ void RemoteSubmixTest::OpenInputStream(const char *address, audio_stream_in_t** ASSERT_NE(nullptr, *streamIn); } -void RemoteSubmixTest::OpenOutputStream(const char *address, audio_stream_out_t** streamOut) { +void RemoteSubmixTest::OpenOutputStream( + const char* address, bool mono, uint32_t sampleRate, audio_stream_out_t** streamOut) { *streamOut = nullptr; struct audio_config configOut = {}; - configOut.channel_mask = AUDIO_CHANNEL_OUT_MONO; - configOut.sample_rate = 48000; + configOut.channel_mask = mono ? AUDIO_CHANNEL_OUT_MONO : AUDIO_CHANNEL_OUT_STEREO; + configOut.sample_rate = sampleRate; status_t result = mDev->open_output_stream(mDev, AUDIO_IO_HANDLE_NONE, AUDIO_DEVICE_NONE, AUDIO_OUTPUT_FLAG_NONE, &configOut, streamOut, address); @@ -111,12 +129,58 @@ void RemoteSubmixTest::OpenOutputStream(const char *address, audio_stream_out_t* ASSERT_NE(nullptr, *streamOut); } +void RemoteSubmixTest::ReadFromStream( + audio_stream_in_t* streamIn, char* buffer, size_t bufferSize) { + ssize_t result = streamIn->read(streamIn, buffer, bufferSize); + EXPECT_EQ(bufferSize, static_cast(result)); +} + +void RemoteSubmixTest::VerifyBufferAllZeroes(char* buffer, size_t bufferSize) { + for (size_t i = 0; i < bufferSize; ++i) { + if (buffer[i]) { + ADD_FAILURE(); + return; + } + } +} + +void RemoteSubmixTest::VerifyBufferNotZeroes(char* buffer, size_t bufferSize) { + for (size_t i = 0; i < bufferSize; ++i) { + if (buffer[i]) return; + } + ADD_FAILURE(); +} + +void RemoteSubmixTest::VerifyOutputInput( + audio_stream_out_t* streamOut, size_t outBufferSize, + audio_stream_in_t* streamIn, size_t inBufferSize, + size_t repeats) { + std::unique_ptr outBuffer(new char[outBufferSize]), inBuffer(new char[inBufferSize]); + GenerateData(outBuffer.get(), outBufferSize); + for (size_t i = 0; i < repeats; ++i) { + WriteIntoStream(streamOut, outBuffer.get(), outBufferSize); + memset(inBuffer.get(), 0, inBufferSize); + ReadFromStream(streamIn, inBuffer.get(), inBufferSize); + if (inBufferSize == outBufferSize) { + ASSERT_EQ(0, memcmp(outBuffer.get(), inBuffer.get(), inBufferSize)); + } else { + VerifyBufferNotZeroes(inBuffer.get(), inBufferSize); + } + } +} + void RemoteSubmixTest::WriteIntoStream( + audio_stream_out_t* streamOut, const char* buffer, size_t bufferSize) { + ssize_t result = streamOut->write(streamOut, buffer, bufferSize); + EXPECT_EQ(bufferSize, static_cast(result)); +} + +void RemoteSubmixTest::WriteSomethingIntoStream( audio_stream_out_t* streamOut, size_t bufferSize, size_t repeats) { std::unique_ptr buffer(new char[bufferSize]); + GenerateData(buffer.get(), bufferSize); for (size_t i = 0; i < repeats; ++i) { - ssize_t result = streamOut->write(streamOut, buffer.get(), bufferSize); - EXPECT_EQ(bufferSize, static_cast(result)); + WriteIntoStream(streamOut, buffer.get(), bufferSize); } } @@ -126,22 +190,143 @@ TEST_F(RemoteSubmixTest, InitSuccess) { // Verifies that when no input was opened, writing into an output stream does not block. TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenNoInput) { - const char *address = "1"; + const char* address = "1"; audio_stream_out_t* streamOut; - OpenOutputStream(address, &streamOut); - WriteIntoStream(streamOut, 1024, 16); + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + WriteSomethingIntoStream(streamOut, 1024, 16); mDev->close_output_stream(mDev, streamOut); } // Verifies that when input is opened but not reading, writing into an output stream does not block. // !!! Currently does not finish because requires setting a parameter from another thread !!! -TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { - const char *address = "1"; +// TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { +// const char* address = "1"; +// audio_stream_out_t* streamOut; +// OpenOutputStream(address, true /*mono*/, 48000, &streamOut); +// audio_stream_in_t* streamIn; +// OpenInputStream(address, true /*mono*/, 48000, &streamIn); +// WriteSomethingIntoStream(streamOut, 1024, 16); +// mDev->close_input_stream(mDev, streamIn); +// mDev->close_output_stream(mDev, streamOut); +// } + +TEST_F(RemoteSubmixTest, OutputAndInput) { + const char* address = "1"; audio_stream_out_t* streamOut; - OpenOutputStream(address, &streamOut); + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); audio_stream_in_t* streamIn; - OpenInputStream(address, &streamIn); - WriteIntoStream(streamOut, 1024, 16); + OpenInputStream(address, true /*mono*/, 48000, &streamIn); + const size_t bufferSize = 1024; + VerifyOutputInput(streamOut, bufferSize, streamIn, bufferSize, 16); mDev->close_input_stream(mDev, streamIn); mDev->close_output_stream(mDev, streamOut); } + +// Verifies that reading and writing into a closed stream fails gracefully. +TEST_F(RemoteSubmixTest, OutputAndInputAfterClose) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, true /*mono*/, 48000, &streamIn); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); + const size_t bufferSize = 1024; + std::unique_ptr buffer(new char[bufferSize]); + memset(buffer.get(), 0, bufferSize); + ASSERT_EQ(0, streamOut->write(streamOut, buffer.get(), bufferSize)); + ASSERT_EQ(static_cast(bufferSize), streamIn->read(streamIn, buffer.get(), bufferSize)); + VerifyBufferAllZeroes(buffer.get(), bufferSize); +} + +TEST_F(RemoteSubmixTest, PresentationPosition) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + uint64_t frames; + struct timespec timestamp; + EXPECT_EQ(0, streamOut->get_presentation_position(streamOut, &frames, ×tamp)); + EXPECT_EQ(uint64_t{0}, frames); + uint64_t prevFrames = frames; + for (size_t i = 0; i < 16; ++i) { + WriteSomethingIntoStream(streamOut, 1024, 1); + EXPECT_EQ(0, streamOut->get_presentation_position(streamOut, &frames, ×tamp)); + EXPECT_LE(prevFrames, frames); + prevFrames = frames; + } + mDev->close_output_stream(mDev, streamOut); +} + +TEST_F(RemoteSubmixTest, RenderPosition) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + uint32_t frames; + EXPECT_EQ(0, streamOut->get_render_position(streamOut, &frames)); + EXPECT_EQ(0U, frames); + uint32_t prevFrames = frames; + for (size_t i = 0; i < 16; ++i) { + WriteSomethingIntoStream(streamOut, 1024, 1); + EXPECT_EQ(0, streamOut->get_render_position(streamOut, &frames)); + EXPECT_LE(prevFrames, frames); + prevFrames = frames; + } + mDev->close_output_stream(mDev, streamOut); +} + +// This requires ENABLE_CHANNEL_CONVERSION to be set in the HAL module +TEST_F(RemoteSubmixTest, MonoToStereoConversion) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, false /*mono*/, 48000, &streamIn); + const size_t bufferSize = 1024; + VerifyOutputInput(streamOut, bufferSize, streamIn, bufferSize * 2, 16); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); +} + +// This requires ENABLE_CHANNEL_CONVERSION to be set in the HAL module +TEST_F(RemoteSubmixTest, StereoToMonoConversion) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, false /*mono*/, 48000, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, true /*mono*/, 48000, &streamIn); + const size_t bufferSize = 1024; + VerifyOutputInput(streamOut, bufferSize * 2, streamIn, bufferSize, 16); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); +} + +// This requires ENABLE_RESAMPLING to be set in the HAL module +TEST_F(RemoteSubmixTest, OutputAndInputResampling) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, true /*mono*/, 24000, &streamIn); + const size_t bufferSize = 1024; + VerifyOutputInput(streamOut, bufferSize * 2, streamIn, bufferSize, 16); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); +} + +// This requires ENABLE_LEGACY_INPUT_OPEN to be set in the HAL module +TEST_F(RemoteSubmixTest, OpenInputMultipleTimes) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + const size_t streamInCount = 3; + audio_stream_in_t* streamIn[streamInCount]; + for (size_t i = 0; i < streamInCount; ++i) { + OpenInputStream(address, true /*mono*/, 48000, &streamIn[i]); + } + const size_t bufferSize = 1024; + for (size_t i = 0; i < streamInCount; ++i) { + VerifyOutputInput(streamOut, bufferSize, streamIn[i], bufferSize, 16); + mDev->close_input_stream(mDev, streamIn[i]); + } + mDev->close_output_stream(mDev, streamOut); +} From 1df8a0039ffaa5161e1ecdfda3ae3f7e5c7068c2 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Tue, 27 Feb 2018 10:06:10 -0800 Subject: [PATCH 40/50] r_submix: Use intermediate pipe in non-blocking mode Switch the pipe into non-blocking mode to prevent stalling when attempting to close it. Simulate circular buffer behavior by flushing old data if there is no more space in the pipe. This removes the need for "exiting=1" parameter. Bug: 73175392 Test: r_submix_tests Change-Id: Iff89980af71112892ff262030e471ae736b1f62a --- modules/audio_remote_submix/audio_hw.cpp | 32 +++---------------- .../tests/remote_submix_tests.cpp | 21 ++++++------ 2 files changed, 15 insertions(+), 38 deletions(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index 8c0c0971..d78e723d 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -418,8 +418,8 @@ static void submix_audio_device_create_pipe_l(struct submix_audio_device * const config->format); const NBAIO_Format offers[1] = {format}; size_t numCounterOffers = 0; - // Create a MonoPipe with optional blocking set to true. - MonoPipe* sink = new MonoPipe(buffer_size_frames, format, true /*writeCanBlock*/); + // Create a MonoPipe with optional blocking set to false. + MonoPipe* sink = new MonoPipe(buffer_size_frames, format, false /*writeCanBlock*/); // Negotiation between the source and sink cannot fail as the device open operation // creates both ends of the pipe using the same audio format. ssize_t index = sink->negotiate(offers, 1, NULL, numCounterOffers); @@ -714,30 +714,8 @@ static int out_dump(const struct audio_stream *stream, int fd) static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { - int exiting = -1; - AudioParameter parms = AudioParameter(String8(kvpairs)); + (void)stream; SUBMIX_ALOGV("out_set_parameters() kvpairs='%s'", kvpairs); - - // FIXME this is using hard-coded strings but in the future, this functionality will be - // converted to use audio HAL extensions required to support tunneling - if ((parms.getInt(String8("exiting"), exiting) == NO_ERROR) && (exiting > 0)) { - struct submix_audio_device * const rsxadev = - audio_stream_get_submix_stream_out(stream)->dev; - pthread_mutex_lock(&rsxadev->lock); - { // using the sink - sp sink = - rsxadev->routes[audio_stream_get_submix_stream_out(stream)->route_handle] - .rsxSink; - if (sink == NULL) { - pthread_mutex_unlock(&rsxadev->lock); - return 0; - } - - ALOGD("out_set_parameters(): shutting down MonoPipe sink"); - sink->shutdown(true); - } // done using the sink - pthread_mutex_unlock(&rsxadev->lock); - } return 0; } @@ -805,12 +783,12 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, return 0; } - // If the write to the sink would block when no input stream is present, flush enough frames + // If the write to the sink would block, flush enough frames // from the pipe to make space to write the most recent data. { const size_t availableToWrite = sink->availableToWrite(); sp source = rsxadev->routes[out->route_handle].rsxSource; - if (rsxadev->routes[out->route_handle].input == NULL && availableToWrite < frames) { + if (availableToWrite < frames) { static uint8_t flush_buffer[64]; const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size; size_t frames_to_flush_from_source = frames - availableToWrite; diff --git a/modules/audio_remote_submix/tests/remote_submix_tests.cpp b/modules/audio_remote_submix/tests/remote_submix_tests.cpp index 2c01c921..36650e76 100644 --- a/modules/audio_remote_submix/tests/remote_submix_tests.cpp +++ b/modules/audio_remote_submix/tests/remote_submix_tests.cpp @@ -198,17 +198,16 @@ TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenNoInput) { } // Verifies that when input is opened but not reading, writing into an output stream does not block. -// !!! Currently does not finish because requires setting a parameter from another thread !!! -// TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { -// const char* address = "1"; -// audio_stream_out_t* streamOut; -// OpenOutputStream(address, true /*mono*/, 48000, &streamOut); -// audio_stream_in_t* streamIn; -// OpenInputStream(address, true /*mono*/, 48000, &streamIn); -// WriteSomethingIntoStream(streamOut, 1024, 16); -// mDev->close_input_stream(mDev, streamIn); -// mDev->close_output_stream(mDev, streamOut); -// } +TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { + const char* address = "1"; + audio_stream_out_t* streamOut; + OpenOutputStream(address, true /*mono*/, 48000, &streamOut); + audio_stream_in_t* streamIn; + OpenInputStream(address, true /*mono*/, 48000, &streamIn); + WriteSomethingIntoStream(streamOut, 1024, 16); + mDev->close_input_stream(mDev, streamIn); + mDev->close_output_stream(mDev, streamOut); +} TEST_F(RemoteSubmixTest, OutputAndInput) { const char* address = "1"; From ab5b51838c94afc60f9979cdde2117930ef90ea9 Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Thu, 1 Mar 2018 13:46:57 -0800 Subject: [PATCH 41/50] r_submix: Fix logspam on pipe corruption Prevent logging an error message on every attempt to write if the FIFO backing up the MonoPipe got corrupted. This condition can be detected by checking for -EIO error code. Bug: 74067530 Test: make audio_utils_fifo_base::mIsShutdown to be set by default, run r_submix_tests and observe logcat Change-Id: I5d67997e902e834f04c10f9ffb39b16cba9c5739 --- modules/audio_remote_submix/audio_hw.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index d78e723d..e826ac31 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -821,6 +821,11 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, written_frames = 0; return 0; + } else if (written_frames == -EIO) { + // receiving -EIO means that the underlying FIFO has shut itself down + // due to reader/writer indices corruption. This state is irreversible, + // so shut down the monopipe. It will be destroyed on the next call to 'write.' + sink->shutdown(true); } else { // write() returned UNDERRUN or WOULD_BLOCK, retry ALOGE("out_write() write to pipe returned unexpected %zd", written_frames); From 16ad46ef48d037635b9a8c890b6c5845fbfaf00c Mon Sep 17 00:00:00 2001 From: Mikhail Naganov Date: Mon, 5 Mar 2018 12:24:45 -0800 Subject: [PATCH 42/50] Revert recent r_submix patches Revert "r_submix: Fix logspam on pipe corruption" This reverts commit ab5b51838c94afc60f9979cdde2117930ef90ea9. Revert "r_submix: Use intermediate pipe in non-blocking mode" This reverts commit 1df8a0039ffaa5161e1ecdfda3ae3f7e5c7068c2. Reason: breaks Android Auto projected mode Bug: 74142786 Test: with Android Auto head unit simulator Change-Id: I8e1bc146a131cb5b1ab88cf242b03a6b02a84339 --- modules/audio_remote_submix/audio_hw.cpp | 37 ++++++++++++++----- .../tests/remote_submix_tests.cpp | 21 ++++++----- 2 files changed, 38 insertions(+), 20 deletions(-) diff --git a/modules/audio_remote_submix/audio_hw.cpp b/modules/audio_remote_submix/audio_hw.cpp index e826ac31..8c0c0971 100644 --- a/modules/audio_remote_submix/audio_hw.cpp +++ b/modules/audio_remote_submix/audio_hw.cpp @@ -418,8 +418,8 @@ static void submix_audio_device_create_pipe_l(struct submix_audio_device * const config->format); const NBAIO_Format offers[1] = {format}; size_t numCounterOffers = 0; - // Create a MonoPipe with optional blocking set to false. - MonoPipe* sink = new MonoPipe(buffer_size_frames, format, false /*writeCanBlock*/); + // Create a MonoPipe with optional blocking set to true. + MonoPipe* sink = new MonoPipe(buffer_size_frames, format, true /*writeCanBlock*/); // Negotiation between the source and sink cannot fail as the device open operation // creates both ends of the pipe using the same audio format. ssize_t index = sink->negotiate(offers, 1, NULL, numCounterOffers); @@ -714,8 +714,30 @@ static int out_dump(const struct audio_stream *stream, int fd) static int out_set_parameters(struct audio_stream *stream, const char *kvpairs) { - (void)stream; + int exiting = -1; + AudioParameter parms = AudioParameter(String8(kvpairs)); SUBMIX_ALOGV("out_set_parameters() kvpairs='%s'", kvpairs); + + // FIXME this is using hard-coded strings but in the future, this functionality will be + // converted to use audio HAL extensions required to support tunneling + if ((parms.getInt(String8("exiting"), exiting) == NO_ERROR) && (exiting > 0)) { + struct submix_audio_device * const rsxadev = + audio_stream_get_submix_stream_out(stream)->dev; + pthread_mutex_lock(&rsxadev->lock); + { // using the sink + sp sink = + rsxadev->routes[audio_stream_get_submix_stream_out(stream)->route_handle] + .rsxSink; + if (sink == NULL) { + pthread_mutex_unlock(&rsxadev->lock); + return 0; + } + + ALOGD("out_set_parameters(): shutting down MonoPipe sink"); + sink->shutdown(true); + } // done using the sink + pthread_mutex_unlock(&rsxadev->lock); + } return 0; } @@ -783,12 +805,12 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, return 0; } - // If the write to the sink would block, flush enough frames + // If the write to the sink would block when no input stream is present, flush enough frames // from the pipe to make space to write the most recent data. { const size_t availableToWrite = sink->availableToWrite(); sp source = rsxadev->routes[out->route_handle].rsxSource; - if (availableToWrite < frames) { + if (rsxadev->routes[out->route_handle].input == NULL && availableToWrite < frames) { static uint8_t flush_buffer[64]; const size_t flushBufferSizeFrames = sizeof(flush_buffer) / frame_size; size_t frames_to_flush_from_source = frames - availableToWrite; @@ -821,11 +843,6 @@ static ssize_t out_write(struct audio_stream_out *stream, const void* buffer, written_frames = 0; return 0; - } else if (written_frames == -EIO) { - // receiving -EIO means that the underlying FIFO has shut itself down - // due to reader/writer indices corruption. This state is irreversible, - // so shut down the monopipe. It will be destroyed on the next call to 'write.' - sink->shutdown(true); } else { // write() returned UNDERRUN or WOULD_BLOCK, retry ALOGE("out_write() write to pipe returned unexpected %zd", written_frames); diff --git a/modules/audio_remote_submix/tests/remote_submix_tests.cpp b/modules/audio_remote_submix/tests/remote_submix_tests.cpp index 36650e76..2c01c921 100644 --- a/modules/audio_remote_submix/tests/remote_submix_tests.cpp +++ b/modules/audio_remote_submix/tests/remote_submix_tests.cpp @@ -198,16 +198,17 @@ TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenNoInput) { } // Verifies that when input is opened but not reading, writing into an output stream does not block. -TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { - const char* address = "1"; - audio_stream_out_t* streamOut; - OpenOutputStream(address, true /*mono*/, 48000, &streamOut); - audio_stream_in_t* streamIn; - OpenInputStream(address, true /*mono*/, 48000, &streamIn); - WriteSomethingIntoStream(streamOut, 1024, 16); - mDev->close_input_stream(mDev, streamIn); - mDev->close_output_stream(mDev, streamOut); -} +// !!! Currently does not finish because requires setting a parameter from another thread !!! +// TEST_F(RemoteSubmixTest, OutputDoesNotBlockWhenInputStuck) { +// const char* address = "1"; +// audio_stream_out_t* streamOut; +// OpenOutputStream(address, true /*mono*/, 48000, &streamOut); +// audio_stream_in_t* streamIn; +// OpenInputStream(address, true /*mono*/, 48000, &streamIn); +// WriteSomethingIntoStream(streamOut, 1024, 16); +// mDev->close_input_stream(mDev, streamIn); +// mDev->close_output_stream(mDev, streamOut); +// } TEST_F(RemoteSubmixTest, OutputAndInput) { const char* address = "1"; From 797ae998eb6681358464fbafe4bb53171b63c4dc Mon Sep 17 00:00:00 2001 From: Ashutosh Joshi Date: Mon, 5 Mar 2018 11:36:49 -0800 Subject: [PATCH 43/50] Update OWNERS Update OWNERS to new stewards. Test: Build compiles. Change-Id: I98f9f58bce6b3686f3ff67f28f3e8d2f2ddf0a88 --- modules/sensors/OWNERS | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/sensors/OWNERS b/modules/sensors/OWNERS index 1af35067..d4393d6a 100644 --- a/modules/sensors/OWNERS +++ b/modules/sensors/OWNERS @@ -1,2 +1,2 @@ -pengxu@google.com -ashutoshj@google.com +arthuri@google.com +bduddie@google.com From d55a49a01e8334d2b2981a951779a8b697ecfcca Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Fri, 2 Mar 2018 12:46:57 -0800 Subject: [PATCH 44/50] Audio V4: Add missing parameter keys Those keys were used as literal strings instead of having a declaration. Bug: 38184704 Test: compile Change-Id: I45709a4a9120e98014d2a4f763fc17f9ef1267ac Merged-In: I45709a4a9120e98014d2a4f763fc17f9ef1267ac Cherry-picked from master Signed-off-by: Kevin Rocard --- include/hardware/audio.h | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index 2d6eb309..53808dd5 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -91,6 +91,17 @@ __BEGIN_DECLS /* Bluetooth SCO wideband */ #define AUDIO_PARAMETER_KEY_BT_SCO_WB "bt_wbs" +/* BT SCO headset name for debug */ +#define AUDIO_PARAMETER_KEY_BT_SCO_HEADSET_NAME "bt_headset_name" + +/* BT SCO HFP control */ +#define AUDIO_PARAMETER_KEY_HFP_ENABLE "hfp_enable" +#define AUDIO_PARAMETER_KEY_HFP_SET_SAMPLING_RATE "hfp_set_sampling_rate" +#define AUDIO_PARAMETER_KEY_HFP_VOLUME "hfp_volume" + +/* Set screen orientation */ +#define AUDIO_PARAMETER_KEY_ROTATION "rotation" + /** * audio stream parameters */ From 909a8f988b4a6ac52491e0af0ceef2cd4dbb25be Mon Sep 17 00:00:00 2001 From: rago Date: Mon, 22 Jan 2018 16:00:30 -0800 Subject: [PATCH 45/50] Support query microphones information. Get list of all/currently active microphones from input stream. Part of the device enumeration feature. Bug: 64038649 Test: Manual Testing and Cts integration test Change-Id: Ibe231c430186c18ce43497c351b7d3e3b2425811 --- include/hardware/audio.h | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index 53808dd5..9ad0f8b5 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -512,6 +512,24 @@ struct audio_stream_in { */ int (*get_mmap_position)(const struct audio_stream_in *stream, struct audio_mmap_position *position); + + /** + * Called by the framework to read active microphones + * + * \param[in] stream the stream object. + * \param[out] mic_array Pointer to first element on array with microphone info + * \param[out] mic_count When called, this holds the value of the max number of elements + * allowed in the mic_array. The actual number of elements written + * is returned here. + * if mic_count is passed as zero, mic_array will not be populated, + * and mic_count will return the actual number of active microphones. + * + * \return 0 if the microphone array is successfully filled. + * -ENOSYS if there is an error filling the data + */ + int (*get_active_microphones)(const struct audio_stream_in *stream, + struct audio_microphone_characteristic_t *mic_array, + size_t *mic_count); }; typedef struct audio_stream_in audio_stream_in_t; @@ -684,6 +702,25 @@ struct audio_hw_device { void (*close_input_stream)(struct audio_hw_device *dev, struct audio_stream_in *stream_in); + /** + * Called by the framework to read available microphones characteristics. + * + * \param[in] dev the hw_device object. + * \param[out] mic_array Pointer to first element on array with microphone info + * \param[out] mic_count When called, this holds the value of the max number of elements + * allowed in the mic_array. The actual number of elements written + * is returned here. + * if mic_count is passed as zero, mic_array will not be populated, + * and mic_count will return the actual number of microphones in the + * system. + * + * \return 0 if the microphone array is successfully filled. + * -ENOSYS if there is an error filling the data + */ + int (*get_microphones)(const struct audio_hw_device *dev, + struct audio_microphone_characteristic_t *mic_array, + size_t *mic_count); + /** This method dumps the state of the audio hardware */ int (*dump)(const struct audio_hw_device *dev, int fd); From 8cf2862f9410d3b581038edd1575c11e4ced9c76 Mon Sep 17 00:00:00 2001 From: Brian Young Date: Fri, 23 Feb 2018 18:03:26 +0000 Subject: [PATCH 46/50] Add "Unlocked device required" key API Add a keymaster parameter for keys that should be inaccessible when the device screen is locked. "Locked" here is a state where the device can be used or accessed without any further trust factor such as a PIN, password, fingerprint, or trusted face or voice. This parameter is added to the Java keystore interface for key creation and import, as well as enums specified by and for the native keystore process. Test: CTS tests in I8a5affd1eaed176756175158e3057e44934fffed Bug: 67752510 Merged-In: I94d8bc5543d00d28064c6e555b38823b70dbfbe6 Change-Id: I94d8bc5543d00d28064c6e555b38823b70dbfbe6 (cherry picked from commit a47bb104965af5dac21bb128adf67932ee05e8e4) --- include/hardware/keymaster_defs.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/include/hardware/keymaster_defs.h b/include/hardware/keymaster_defs.h index 6e812f29..cec486e7 100644 --- a/include/hardware/keymaster_defs.h +++ b/include/hardware/keymaster_defs.h @@ -112,6 +112,8 @@ typedef enum { KM_TAG_ALLOW_WHILE_ON_BODY = KM_BOOL | 506, /* Allow key to be used after authentication timeout * if device is still on-body (requires secure * on-body sensor. */ + KM_TAG_UNLOCKED_DEVICE_REQUIRED = KM_BOOL | 508, /* Require the device screen to be unlocked if the + * key is used. */ /* Application access control */ KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600, /* Specified to indicate key is usable by all @@ -452,6 +454,7 @@ typedef enum { KM_ERROR_KEYMASTER_NOT_CONFIGURED = -64, KM_ERROR_ATTESTATION_APPLICATION_ID_MISSING = -65, KM_ERROR_CANNOT_ATTEST_IDS = -66, + KM_ERROR_DEVICE_LOCKED = -72, KM_ERROR_UNIMPLEMENTED = -100, KM_ERROR_VERSION_MISMATCH = -101, From 0360e255f14ce24ff315af266818da7d411474c4 Mon Sep 17 00:00:00 2001 From: Kevin Rocard Date: Mon, 26 Mar 2018 17:13:12 -0700 Subject: [PATCH 47/50] Audio V4: Add metadata update to legacy API The metadata API was not present in the legacy HAL API which lots of developer still use. Test: Check the method is correctly called on each track change Bug: 38184704 Bug: 69623109 Change-Id: I46a9db5a67baef52844ed85296a529402e00f4cb Signed-off-by: Kevin Rocard --- include/hardware/audio.h | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/include/hardware/audio.h b/include/hardware/audio.h index 9ad0f8b5..10a8789a 100644 --- a/include/hardware/audio.h +++ b/include/hardware/audio.h @@ -212,13 +212,24 @@ typedef enum { give time for gapless track switch */ } audio_drain_type_t; +typedef struct source_metadata { + size_t track_count; + /** Array of metadata of each track connected to this source. */ + struct playback_track_metadata* tracks; +} source_metadata_t; + +typedef struct sink_metadata { + size_t track_count; + /** Array of metadata of each track connected to this sink. */ + struct record_track_metadata* tracks; +} sink_metadata_t; + /** * audio_stream_out is the abstraction interface for the audio output hardware. * * It provides information about various properties of the audio output * hardware driver. */ - struct audio_stream_out { /** * Common methods of the audio stream out. This *must* be the first member of audio_stream_out @@ -403,6 +414,13 @@ struct audio_stream_out { */ int (*get_mmap_position)(const struct audio_stream_out *stream, struct audio_mmap_position *position); + + /** + * Called when the metadata of the stream's source has been changed. + * @param source_metadata Description of the audio that is played by the clients. + */ + void (*update_source_metadata)(struct audio_stream_out *stream, + const struct source_metadata* source_metadata); }; typedef struct audio_stream_out audio_stream_out_t; @@ -530,6 +548,13 @@ struct audio_stream_in { int (*get_active_microphones)(const struct audio_stream_in *stream, struct audio_microphone_characteristic_t *mic_array, size_t *mic_count); + + /** + * Called when the metadata of the stream's sink has been changed. + * @param sink_metadata Description of the audio that is recorded by the clients. + */ + void (*update_sink_metadata)(struct audio_stream_in *stream, + const struct sink_metadata* sink_metadata); }; typedef struct audio_stream_in audio_stream_in_t; From 28310aa8685fbc65aaa1ff1134b02cd66850d997 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Thu, 15 Mar 2018 21:20:55 -0700 Subject: [PATCH 48/50] hwcomposer2: add render intent support Add HWC2_FUNCTION_GET_RENDER_INTENTS HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX and fix HWC2_FUNCTION_SET_PER_FRAME_METADATA to be per-layer. Bug: 73824924 Test: manual Change-Id: I25e34c4bf3dc5d496ea23c2d13419dd28f3e6cca --- include/hardware/hwcomposer2.h | 156 ++++++++++++++++++++++++++------- 1 file changed, 122 insertions(+), 34 deletions(-) diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h index 7b7db108..0138cbb0 100644 --- a/include/hardware/hwcomposer2.h +++ b/include/hardware/hwcomposer2.h @@ -263,11 +263,14 @@ typedef enum { HWC2_FUNCTION_SET_VSYNC_ENABLED, HWC2_FUNCTION_VALIDATE_DISPLAY, HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, - HWC2_FUNCTION_SET_PER_FRAME_METADATA, + HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA, HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS, HWC2_FUNCTION_SET_READBACK_BUFFER, HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES, - HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE + HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE, + HWC2_FUNCTION_GET_RENDER_INTENTS, + HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT, + HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX } hwc2_function_descriptor_t; /* Layer requests returned from getDisplayRequests */ @@ -513,11 +516,14 @@ static inline const char* getFunctionDescriptorName( case HWC2_FUNCTION_SET_VSYNC_ENABLED: return "SetVsyncEnabled"; case HWC2_FUNCTION_VALIDATE_DISPLAY: return "ValidateDisplay"; case HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR: return "SetLayerFloatColor"; - case HWC2_FUNCTION_SET_PER_FRAME_METADATA: return "SetPerFrameMetadata"; + case HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA: return "SetLayerPerFrameMetadata"; case HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS: return "GetPerFrameMetadataKeys"; case HWC2_FUNCTION_SET_READBACK_BUFFER: return "SetReadbackBuffer"; case HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES: return "GetReadbackBufferAttributes"; case HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE: return "GetReadbackBufferFence"; + case HWC2_FUNCTION_GET_RENDER_INTENTS: return "GetRenderIntents"; + case HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT: return "SetColorModeWithRenderIntent"; + case HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX: return "GetDataspaceSaturationMatrix"; default: return "Unknown"; } } @@ -708,11 +714,14 @@ enum class FunctionDescriptor : int32_t { SetVsyncEnabled = HWC2_FUNCTION_SET_VSYNC_ENABLED, ValidateDisplay = HWC2_FUNCTION_VALIDATE_DISPLAY, SetLayerFloatColor = HWC2_FUNCTION_SET_LAYER_FLOAT_COLOR, - SetPerFrameMetadata = HWC2_FUNCTION_SET_PER_FRAME_METADATA, + SetLayerPerFrameMetadata = HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA, GetPerFrameMetadataKeys = HWC2_FUNCTION_GET_PER_FRAME_METADATA_KEYS, SetReadbackBuffer = HWC2_FUNCTION_SET_READBACK_BUFFER, GetReadbackBufferAttributes = HWC2_FUNCTION_GET_READBACK_BUFFER_ATTRIBUTES, GetReadbackBufferFence = HWC2_FUNCTION_GET_READBACK_BUFFER_FENCE, + GetRenderIntents = HWC2_FUNCTION_GET_RENDER_INTENTS, + SetColorModeWithRenderIntent = HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT, + GetDataspaceSaturationMatrix = HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX, }; TO_STRING(hwc2_function_descriptor_t, FunctionDescriptor, getFunctionDescriptorName) @@ -1014,6 +1023,27 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_REGISTER_CALLBACK)( int32_t /*hwc2_callback_descriptor_t*/ descriptor, hwc2_callback_data_t callbackData, hwc2_function_pointer_t pointer); +/* getDataspaceSaturationMatrix(..., dataspace, outMatrix) + * Descriptor: HWC2_FUNCTION_GET_DATASPACE_SATURATION_MATRIX + * Provided by HWC2 devices which don't return nullptr function pointer. + * + * Get the saturation matrix of the specified dataspace. The saturation matrix + * can be used to approximate the dataspace saturation operation performed by + * the HWC2 device when non-colorimetric mapping is allowed. It is to be + * applied on linear pixel values. + * + * Parameters: + * dataspace - the dataspace to query for + * outMatrix - a column-major 4x4 matrix (16 floats). It must be an identity + * matrix unless dataspace is HAL_DATASPACE_SRGB_LINEAR. + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_PARAMETER - dataspace was invalid + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_DATASPACE_SATURATION_MATRIX)( + hwc2_device_t* device, int32_t /*android_dataspace_t*/ dataspace, + float* outMatrix); + /* * Display Functions * @@ -1191,6 +1221,35 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_COLOR_MODES)( hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumModes, int32_t* /*android_color_mode_t*/ outModes); +/* getRenderIntents(..., mode, outNumIntents, outIntents) + * Descriptor: HWC2_FUNCTION_GET_RENDER_INTENTS + * Provided by HWC2 devices which don't return nullptr function pointer. + * + * Returns the render intents supported on this display. + * + * The valid render intents can be found in android_render_intent_v1_1_t in + * . All HWC2 devices must support at least + * HAL_RENDER_INTENT_COLORIMETRIC. + * + * outNumIntents may be NULL to retrieve the number of intents which will be + * returned. + * + * Parameters: + * mode - the color mode to query the render intents for + * outNumIntents - if outIntents was NULL, the number of intents which would + * have been returned; if outIntents was not NULL, the number of intents + * returned, which must not exceed the value stored in outNumIntents + * prior to the call; pointer will be non-NULL + * outIntents - an array of render intents + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_RENDER_INTENTS)( + hwc2_device_t* device, hwc2_display_t display, int32_t mode, + uint32_t* outNumIntents, + int32_t* /*android_render_intent_v1_1_t*/ outIntents); + /* getDisplayAttribute(..., config, attribute, outValue) * Descriptor: HWC2_FUNCTION_GET_DISPLAY_ATTRIBUTE * Must be provided by all HWC2 devices @@ -1515,8 +1574,8 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_CLIENT_TARGET)( * * Sets the color mode of the given display. * - * Upon returning from this function, the color mode change must have fully - * taken effect. + * This must be called outside of validateDisplay/presentDisplay, and it takes + * effect on next presentDisplay. * * The valid color modes can be found in android_color_mode_t in * . All HWC2 devices must support at least @@ -1535,6 +1594,34 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_COLOR_MODE)( hwc2_device_t* device, hwc2_display_t display, int32_t /*android_color_mode_t*/ mode); +/* setColorModeWithIntent(..., mode, intent) + * Descriptor: HWC2_FUNCTION_SET_COLOR_MODE_WITH_RENDER_INTENT + * Provided by HWC2 devices which don't return nullptr function pointer. + * + * This must be called outside of validateDisplay/presentDisplay, and it takes + * effect on next presentDisplay. + * + * The valid color modes and render intents can be found in + * android_color_mode_t and android_render_intent_v1_1_t in + * . All HWC2 devices must support at least + * HAL_COLOR_MODE_NATIVE and HAL_RENDER_INTENT_COLORIMETRIC, and displays are + * assumed to be in this mode and intent upon hotplug. + * + * Parameters: + * mode - the mode to set + * intent - the intent to set + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_BAD_PARAMETER - mode/intent is not a valid color mode or + * render intent + * HWC2_ERROR_UNSUPPORTED - mode or intent is not supported on this display + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_COLOR_MODE_WITH_RENDER_INTENT)( + hwc2_device_t* device, hwc2_display_t display, + int32_t /*android_color_mode_t*/ mode, + int32_t /*android_render_intent_v1_1_t */ intent); + /* setColorTransform(..., matrix, hint) * Descriptor: HWC2_FUNCTION_SET_COLOR_TRANSFORM * Must be provided by all HWC2 devices @@ -1610,34 +1697,6 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_PER_FRAME_METADATA_KEYS)( hwc2_device_t* device, hwc2_display_t display, uint32_t* outNumKeys, int32_t* /*hwc2_per_frame_metadata_key_t*/ outKeys); -/* setPerFrameMetadata(..., numMetadata, metadata) - * Descriptor: HWC2_FUNCTION_SET_PER_FRAME_METADATA - * Optional for HWC2 devices - * - * If supported (getFunction(HWC2_FUNCTION_SET_PER_FRAME_METADATA) is non-null), - * sets the metadata for the given display for all following frames. - * - * Upon returning from this function, the metadata change must have - * fully taken effect. - * - * This function will only be called if getPerFrameMetadataKeys is non-NULL - * and returns at least one key. - * - * Parameters: - * numKeys is the number of elements in each of the keys and metadata arrays - * outKeys is a pointer to the array of keys. - * outMetadata is a pointer to the corresponding array of metadata. - * - * Returns HWC2_ERROR_NONE or one of the following errors: - * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in - * HWC2_ERROR_BAD_PARAMETER - metadata is not valid - * HWC2_ERROR_UNSUPPORTED - metadata is not supported on this display - */ -typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_PER_FRAME_METADATA)( - hwc2_device_t* device, hwc2_display_t display, - uint32_t numMetadata, const int32_t* /*hw2_per_frame_metadata_key_t*/ outKeys, - const float* outMetadata); - /* setOutputBuffer(..., buffer, releaseFence) * Descriptor: HWC2_FUNCTION_SET_OUTPUT_BUFFER * Must be provided by all HWC2 devices @@ -1977,6 +2036,35 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_LAYER_SURFACE_DAMAGE)( hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, hwc_region_t damage); +/* setLayerPerFrameMetadata(..., numMetadata, metadata) + * Descriptor: HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA + * Optional for HWC2 devices + * + * If supported (getFunction(HWC2_FUNCTION_SET_LAYER_PER_FRAME_METADATA) is + * non-null), sets the metadata for the given display for all following + * frames. + * + * Upon returning from this function, the metadata change must have + * fully taken effect. + * + * This function will only be called if getPerFrameMetadataKeys is non-NULL + * and returns at least one key. + * + * Parameters: + * numElements is the number of elements in each of the keys and metadata arrays + * keys is a pointer to the array of keys. + * outMetadata is a pointer to the corresponding array of metadata. + * + * Returns HWC2_ERROR_NONE or one of the following errors: + * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in + * HWC2_ERROR_BAD_PARAMETER - metadata is not valid + * HWC2_ERROR_UNSUPPORTED - metadata is not supported on this display + */ +typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_LAYER_PER_FRAME_METADATA)( + hwc2_device_t* device, hwc2_display_t display, hwc2_layer_t layer, + uint32_t numElements, const int32_t* /*hw2_per_frame_metadata_key_t*/ keys, + const float* metadata); + /* * Layer State Functions * From 5838dff356b50586f6cb549c859e5d6e1611f0a6 Mon Sep 17 00:00:00 2001 From: Marissa Wall Date: Thu, 26 Apr 2018 10:17:05 -0700 Subject: [PATCH 49/50] gralloc1: security hardening Add support for getTransportSize, validateBufferSize and importBuffer to gralloc1. Bug: 66876469 Test: Manual Change-Id: Ie3435297cff2d3272df658af262905c13f403e4b --- include/hardware/gralloc1.h | 95 ++++++++++++++++++++++++++++++++++++- 1 file changed, 94 insertions(+), 1 deletion(-) diff --git a/include/hardware/gralloc1.h b/include/hardware/gralloc1.h index 0a6843f0..03e84322 100644 --- a/include/hardware/gralloc1.h +++ b/include/hardware/gralloc1.h @@ -155,7 +155,10 @@ typedef enum { GRALLOC1_FUNCTION_UNLOCK = 20, GRALLOC1_FUNCTION_SET_LAYER_COUNT = 21, GRALLOC1_FUNCTION_GET_LAYER_COUNT = 22, - GRALLOC1_LAST_FUNCTION = 22, + GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE = 23, + GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE = 24, + GRALLOC1_FUNCTION_IMPORT_BUFFER = 25, + GRALLOC1_LAST_FUNCTION = 25, } gralloc1_function_descriptor_t; typedef enum { @@ -670,6 +673,65 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_PRODUCER_USAGE)( typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_STRIDE)( gralloc1_device_t* device, buffer_handle_t buffer, uint32_t* outStride); +/* getTransportSize(..., outNumFds, outNumInts) + * Function descriptor: GRALLOC1_FUNCTION_GET_TRANSPORT_SIZE + * This function is optional for all gralloc1 devices. + * + * Get the transport size of a buffer. An imported buffer handle is a raw + * buffer handle with the process-local runtime data appended. This + * function, for example, allows a caller to omit the process-local + * runtime data at the tail when serializing the imported buffer handle. + * + * Note that a client might or might not omit the process-local runtime + * data when sending an imported buffer handle. The mapper must support + * both cases on the receiving end. + * + * Parameters: + * outNumFds - the number of file descriptors needed for transport + * outNumInts - the number of integers needed for transport + * + * 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 numFds + * and numInts; see note [1] in this section's header for more information + */ +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_GET_TRANSPORT_SIZE)( + gralloc1_device_t* device, buffer_handle_t buffer, uint32_t *outNumFds, + uint32_t *outNumInts); + +typedef struct gralloc1_buffer_descriptor_info { + uint32_t width; + uint32_t height; + uint32_t layerCount; + int32_t /*android_pixel_format_t*/ format; + uint64_t producerUsage; + uint64_t consumerUsage; +} gralloc1_buffer_descriptor_info_t; + +/* validateBufferSize(..., ) + * Function descriptor: GRALLOC1_FUNCTION_VALIDATE_BUFFER_SIZE + * This function is optional for all gralloc1 devices. + * + * Validate that the buffer can be safely accessed by a caller who assumes + * the specified descriptorInfo and stride. This must at least validate + * that the buffer size is large enough. Validating the buffer against + * individual buffer attributes is optional. + * + * Parameters: + * descriptor - specifies the attributes of the buffer + * stride - the buffer stride returned by IAllocator::allocate + * + * Returns GRALLOC1_ERROR_NONE or one of the following errors: + * GRALLOC1_ERROR_BAD_HANDLE - the buffer handle is invalid + * GRALLOC1_ERROR_BAD_VALUE - when buffer cannot be safely accessed + * GRALLOC1_ERROR_UNSUPPORTED - the device is unable to validate the buffer + * size; see note [1] in this section's header for more information + */ +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_VALIDATE_BUFFER_SIZE)( + gralloc1_device_t* device, buffer_handle_t buffer, + const gralloc1_buffer_descriptor_info_t* descriptorInfo, + uint32_t stride); + /* * Buffer management functions */ @@ -723,6 +785,37 @@ typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_ALLOCATE)( const gralloc1_buffer_descriptor_t* descriptors, buffer_handle_t* outBuffers); +/* importBuffer(..., rawHandle, outBuffer); + * Function descriptor: GRALLOC1_FUNCTION_IMPORT_BUFFER + * This function is optional for all gralloc1 devices. + * When supported, GRALLOC1_CAPABILITY_RELEASE_IMPLY_DELETE must also be + * supported. + * + * Explictly imports a buffer into a proccess. + * + * This function can be called in place of retain when a raw buffer handle is + * received by a remote process. Import producess a import handle that can + * be used to access the underlying graphic buffer. The new import handle has a + * ref count of 1. + * + * This function must at least validate the raw handle before creating the + * imported handle. It must also support importing the same raw handle + * multiple times to create multiple imported handles. The imported handle + * must be considered valid everywhere in the process. + * + * Parameters: + * rawHandle - the raw buffer handle to import + * outBuffer - a handle to the newly imported buffer + * + * 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 import to this + * buffer at this time + */ +typedef int32_t /*gralloc1_error_t*/ (*GRALLOC1_PFN_IMPORT_BUFFER)( + gralloc1_device_t* device, const buffer_handle_t rawHandle, + buffer_handle_t* outBuffer); + /* retain(..., buffer) * Function descriptor: GRALLOC1_FUNCTION_RETAIN * Must be provided by all gralloc1 devices From af153e0a5d081c7ac8045a73a48498b619c97abf Mon Sep 17 00:00:00 2001 From: Dan Stoza Date: Tue, 15 May 2018 13:09:51 -0700 Subject: [PATCH 50/50] hwc2: Fix readback docs Fixes a couple of problems with the return codes in the readback documentation and adds a paragraph of clarification about when getReadbackBufferAttributes will be called. Bug: 67048889 Test: N/A, doc fix only Change-Id: I3ea1a6993323f7ce12c36a377bf69e2866b18082 --- include/hardware/hwcomposer2.h | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/include/hardware/hwcomposer2.h b/include/hardware/hwcomposer2.h index 0138cbb0..c9809ce8 100644 --- a/include/hardware/hwcomposer2.h +++ b/include/hardware/hwcomposer2.h @@ -1774,15 +1774,19 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_SET_POWER_MODE)( * output of the display remains the same (subject to the note about protected * content in the description of setReadbackBuffer). * + * If the active configuration or color mode of this display has changed since + * the previous call to this function, it will be called again prior to setting + * a readback buffer such that the returned format and dataspace can be updated + * accordingly. + * * Parameters: * outFormat - the format the client should use when allocating a device - * readback buffer + * readback buffer; pointer will be non-NULL * outDataspace - the dataspace the client will use when interpreting the - * contents of a device readback buffer + * contents of a device readback buffer; pointer will be non-NULL * * Returns HWC2_ERROR_NONE or one of the following errors: * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in - * HWC2_ERROR_UNSUPPORTED - mode was a valid power mode, but is not supported * * See also: * setReadbackBuffer @@ -1824,8 +1828,12 @@ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_READBACK_BUFFER_ATTRIBUTES)( * * Returns HWC2_ERROR_NONE or one of the following errors: * HWC2_ERROR_BAD_DISPLAY - an invalid display handle was passed in - * HWC2_ERROR_UNSUPPORTED - mode was a valid power mode, but is not supported - * + * HWC2_ERROR_NO_RESOURCES - the readback operation was successful, but + * resulted in a different validate result than would have occurred + * without readback + * HWC2_ERROR_UNSUPPORTED - the readback operation was unsuccessful because + * of resource constraints, the presence of protected content, or other + * reasons; -1 must be returned in outFence */ typedef int32_t /*hwc2_error_t*/ (*HWC2_PFN_GET_READBACK_BUFFER_FENCE)( hwc2_device_t* device, hwc2_display_t display,