display: Add rotation angle API 20/282720/13
authorTaeminYeom <taemin.yeom@samsung.com>
Tue, 11 Oct 2022 01:14:47 +0000 (10:14 +0900)
committerChanwoo Choi <cw00.choi@samsung.com>
Fri, 23 Dec 2022 02:39:44 +0000 (11:39 +0900)
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 <taemin.yeom@samsung.com>
[cw00.choi: Add DEVICE_DISPLAY_ROTATION_ANGLE_DEGREE_360 enum]
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
CMakeLists.txt
include/display-internal.h
packaging/capi-system-device.spec
src/display.c

index b10ff46..0631b8d 100644 (file)
@@ -15,6 +15,8 @@ SET(PKG_MODULES
                vconf
                capi-base-common
                capi-system-info
+               capi-system-sensor
+               sensor
                gio-2.0
                tracker
                libsyscommon
index 3bc1aee..4872c92 100644 (file)
@@ -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)
index f6a904e..3711d7a 100644 (file)
@@ -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)
index 0a9d9ce..3044ca9 100644 (file)
 
 #include <stdio.h>
 #include <errno.h>
+
 #include <vconf.h>
 #include <libsyscommon/libgdbus.h>
 #include <system_info.h>
+#include <sensor.h>
+#include <sensor_internal.h>
+#include <glib.h>
 
 #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
+}