From: TaeminYeom Date: Tue, 11 Oct 2022 01:14:47 +0000 (+0900) Subject: display: Add rotation angle API X-Git-Tag: accepted/tizen/unified/20221226.165751~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=b0ba0fa91f7b6dadac40bb06d3c3d8d10c8f54e5;p=platform%2Fcore%2Fapi%2Fdevice.git display: Add rotation angle API rotation angle means "physical display" angle. Clients can rotate display or check current display angle. API function -device_display_get_rotation_angle : get current display rotation angle -device_display_set_rotation_angle : rotate physical display to set angle Enumeration -device_display_rotation_angle_e DEVICE_DISPLAY_ROTATION_ANGLE_UNKNOWN : It can be seen in laid device DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0 : Initial display rotation angle DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_90 : 90° rotation angle DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_180 : 180° rotation angle DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_270 : 270° rotation angle DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360 : 360° rotation angle -device_display_rotation_direction_e DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE : Rotate clockwise direction DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE : Rotate counter clockwise direction Change-Id: Iae840b217977e2540883fec31f5e2631aa93b967 Signed-off-by: TaeminYeom [cw00.choi: Add DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360 enum] Signed-off-by: Chanwoo Choi --- diff --git a/CMakeLists.txt b/CMakeLists.txt index b10ff46..0631b8d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,8 @@ SET(PKG_MODULES vconf capi-base-common capi-system-info + capi-system-sensor + sensor gio-2.0 tracker libsyscommon diff --git a/include/display-internal.h b/include/display-internal.h index 3bc1aee..4872c92 100644 --- a/include/display-internal.h +++ b/include/display-internal.h @@ -44,6 +44,34 @@ typedef enum DISPLAY_WHITE_BALANCE_B_OFFSET, /**< White balance B Offset */ } display_white_balance_e; + +/** + * @brief Enumeration for the available display rotation states. + * * @since_tizen 7.0 + */ + +typedef enum +{ + DEVICE_DISPLAY_ROTATION_ANGLE_UNKNOWN = -1, /**< Unknown state. It can be seen in laid device */ + DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0 = 0, /**< Display rotation state is 0 degree */ + DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_90 = 90, /**< Display rotation state is 90 degree */ + DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_180 = 180, /**< Display rotation state is 180 degree */ + DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_270 = 270, /**< Display rotation state is 270 degree */ + DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360 = 360, /**< Display rotation state is 360 degree */ +} device_display_rotation_angle_e; + + +/** + * @brief Enumeration for the display rotation directions. + * @since_tizen 7.0 + */ + +typedef enum +{ + DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE, /**< Rotate with clockwise direction */ + DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE, /**< Rotate with counter clockwise direction */ +} device_display_rotation_direction_e; + /** * @brief Gets the display brightness value. * @since_tizen @if MOBILE 5.0 @elseif WEARABLE 5.0 @endif @@ -143,6 +171,57 @@ int device_display_change_state_by_reason(display_state_e type, const char *reas */ int is_feature_display_supported(void); + +/** + * @brief Get display rotation angle + * @since_tizen 7.0 + * @privilege %http://tizen.org/privilege/display + * @remarks It shows the physical display angle, not SW screen angle. + * @param[in] display_index The index of the display \n + * It can be greater than or equal to @c 0 and less than the number of displays returned by device_display_get_numbers(). \n + * The index zero is always assigned to the main display + * @param[out] angle The type is display rotation angle\n + * DEVICE_DISPLAY_ROTATION_ANGLE_UNKNOWN\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_90\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_180\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_270\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360\n + * @return @c 0 on success, + * otherwise a negative error value + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_PERMISSION_DENIED Permission denied + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_display_get_rotation_angle(int display_index, device_display_rotation_angle_e *angle); + +/** + * @brief Set display rotation angle + * @since_tizen 7.0 + * @privilege %http://tizen.org/privilege/display + * @remarks It shows the physical display angle, not SW screen angle. + * @param[in] display_index The index of the display \n + * It can be greater than or equal to @c 0 and less than the number of displays returned by device_display_get_numbers(). \n + * The index zero is always assigned to the main display + * @param[in] angle The type is display rotation angle\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_90\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_180\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_270\n + * DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360\n + * @param[in] direction The type is display rotation direction\n + * DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE\n + * DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE\n + * @return @c 0 on success, + * otherwise a negative error value + * @retval #DEVICE_ERROR_NONE Successful + * @retval #DEVICE_ERROR_INVALID_PARAMETER Invalid parameter + * @retval #DEVICE_ERROR_PERMISSION_DENIED Permission denied + * @retval #DEVICE_ERROR_OPERATION_FAILED Operation failed + */ +int device_display_set_rotation_angle(int display_index, device_display_rotation_angle_e angle, device_display_rotation_direction_e direction); + /** * @platform * @brief Check display state feature(http://tizen.org/feature/display.state) diff --git a/packaging/capi-system-device.spec b/packaging/capi-system-device.spec index f6a904e..3711d7a 100644 --- a/packaging/capi-system-device.spec +++ b/packaging/capi-system-device.spec @@ -9,6 +9,8 @@ Source1: capi-system-device.manifest BuildRequires: cmake BuildRequires: pkgconfig(capi-base-common) BuildRequires: pkgconfig(capi-system-info) +BuildRequires: pkgconfig(capi-system-sensor) +BuildRequires: pkgconfig(sensor) BuildRequires: pkgconfig(dlog) BuildRequires: pkgconfig(vconf) BuildRequires: pkgconfig(gio-2.0) diff --git a/src/display.c b/src/display.c index 0a9d9ce..3044ca9 100644 --- a/src/display.c +++ b/src/display.c @@ -17,9 +17,13 @@ #include #include + #include #include #include +#include +#include +#include #include "display.h" #include "display-internal.h" @@ -36,6 +40,8 @@ #define METHOD_CHANGE_STATE_BY_REASON "ChangeStateByReason" #define METHOD_GET_WHITE_BALANCE "GetWhiteBalance" #define METHOD_SET_WHITE_BALANCE "SetWhiteBalance" +#define METHOD_GET_ROTATION_ANGLE "GetRotationAngle" +#define METHOD_SET_ROTATION_ANGLE "SetRotationAngle" #define STR_LCD_OFF "lcdoff" #define STR_LCD_DIM "lcddim" @@ -52,6 +58,9 @@ struct display { int dim_max; } *display_arr; +static bool g_sensor_initialized; +static sensor_listener_h g_sensor_listener_handle; + static int alloc_display(void) { int i; @@ -475,6 +484,196 @@ int is_feature_display_supported(void) return true; } +static int display_sensor_listener_start(void) +{ + sensor_h *sensor_handle = NULL; + int count, ret; + bool supported = false; + + if (!g_sensor_initialized) { + sensor_is_supported(AUTO_ROTATION_SENSOR, &supported); + if (!supported) { + _E("Auto rotation sensor is not supported in this device"); + return DEVICE_ERROR_OPERATION_FAILED; + } + + ret = sensor_get_sensor_list(AUTO_ROTATION_SENSOR, &sensor_handle, &count); + if (ret < 0 || !sensor_handle || count <= 0) { + _E("Failed to get sensor list"); + return DEVICE_ERROR_OPERATION_FAILED; + } + + ret = sensor_create_listener(sensor_handle[0], &g_sensor_listener_handle); + if (ret < 0) { + _E("Failed to create sensor listener"); + free(sensor_handle); + return DEVICE_ERROR_OPERATION_FAILED; + } + + free(sensor_handle); + g_sensor_initialized = true; + } + + ret = sensor_listener_start(g_sensor_listener_handle); + if (ret < 0) { + _E("Failed to start auto-rotation sensor"); + return DEVICE_ERROR_OPERATION_FAILED; + } + + return DEVICE_ERROR_NONE; +} + +static int display_sensor_listener_stop(void) +{ + int ret; + ret = sensor_listener_stop(g_sensor_listener_handle); + if (ret < 0) + return ret; + + return DEVICE_ERROR_NONE; +} + +static int sensor_get_rotation_angle(device_display_rotation_angle_e *angle) +{ + int ret, count, event; + sensor_event_s *events = NULL; + + ret = display_sensor_listener_start(); + if (ret < 0) + return ret; + + ret = sensor_listener_read_data_list(g_sensor_listener_handle, &events, &count); + if (ret < 0 || count <= 0) { + _E("Failed to read the value of auto-rotation sensor"); + display_sensor_listener_stop(); + return DEVICE_ERROR_OPERATION_FAILED; + } + + event = (int)events->values[0]; + switch (event) { + case AUTO_ROTATION_DEGREE_0: + *angle = DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0; + break; + case AUTO_ROTATION_DEGREE_90: + *angle = DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_90; + break; + case AUTO_ROTATION_DEGREE_180: + *angle = DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_180; + break; + case AUTO_ROTATION_DEGREE_270: + *angle = DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_270; + break; + default: + *angle = DEVICE_DISPLAY_ROTATION_ANGLE_UNKNOWN; + break; + } + + free(events); + return display_sensor_listener_stop(); +} + +int device_display_get_rotation_angle(int display_index, int *angle) +{ + int ret = 0, reply_val = 0; + GVariant *reply; + + ret = is_feature_display_supported(); + if (!ret) + return DEVICE_ERROR_NOT_SUPPORTED; + + if (display_cnt < 0) { + ret = device_display_get_numbers(&display_cnt); + if (ret < 0) + return ret; + } + + if (display_index < 0 || display_index >= display_cnt || !angle) + return DEVICE_ERROR_INVALID_PARAMETER; + + /* Get the display rotation angle from deviced */ + ret = gdbus_call_sync_with_reply(DEVICED_BUS_NAME, + DEVICED_PATH_DISPLAY, + DEVICED_INTERFACE_DISPLAY, + METHOD_GET_ROTATION_ANGLE, + g_variant_new("(i)", display_index), + &reply); + + if (ret < 0) { + _E("Failed to call dbus method to get the rotation angle"); + return ret; + } + + g_variant_get(reply, "(ii)", &ret, &reply_val); + g_variant_unref(reply); + if (ret < 0 && ret != -ENODEV) { + _E("Failed to get display rotation angle"); + return ret; + } else if (ret >= 0) { + *angle = reply_val; + return DEVICE_ERROR_NONE; + } + + /* + * If the device don't support display rotation, + * get the display rotation angle using capi-system-sensor. + */ + return sensor_get_rotation_angle(angle); +} + +int device_display_set_rotation_angle(int display_index, + device_display_rotation_angle_e angle, + device_display_rotation_direction_e direction) +{ + int ret, reply; + + ret = is_feature_display_supported(); + if (!ret) + return DEVICE_ERROR_NOT_SUPPORTED; + + if (display_cnt < 0) { + ret = device_display_get_numbers(&display_cnt); + if (ret < 0) + return ret; + } + + if (display_index < 0 || display_index >= display_cnt) + return DEVICE_ERROR_INVALID_PARAMETER; + + if (angle < DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_0 + || angle > DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360) + return DEVICE_ERROR_INVALID_PARAMETER; + + switch (direction) { + case DEVICE_DISPLAY_ROTATION_DIRECTION_CLOCKWISE: + case DEVICE_DISPLAY_ROTATION_DIRECTION_COUNTER_CLOCKWISE: + break; + default: + return DEVICE_ERROR_INVALID_PARAMETER; + } + + ret = gdbus_call_sync_with_reply_int(DEVICED_BUS_NAME, + DEVICED_PATH_DISPLAY, + DEVICED_INTERFACE_DISPLAY, + METHOD_SET_ROTATION_ANGLE, + g_variant_new("(iii)", display_index, angle, direction), + &reply); + + if (ret < 0) { + _E("Failed to call dbus method to set the rotation angle"); + return ret; + } + + if (reply == -ENODEV) { + _E("Set display rotation is not supported"); + return DEVICE_ERROR_OPERATION_FAILED; + } else if (ret < 0) { + _E("Failed to set display rotation angle"); + return DEVICE_ERROR_OPERATION_FAILED; + } + + return DEVICE_ERROR_NONE; +} + int is_feature_display_state_supported(void) { int ret_val; @@ -589,4 +788,4 @@ int device_display_get_white_balance(int display_index, display_white_balance_e *value = reply; return DEVICE_ERROR_NONE; -} \ No newline at end of file +}