From 967d236a6033f8764dd7cb33dccad3668f0d37c0 Mon Sep 17 00:00:00 2001 From: Sehong Na Date: Sat, 31 May 2014 12:34:41 +0900 Subject: [PATCH] Initialize Tizen 2.3 --- AUTHORS | 4 + CMakeLists.txt | 86 +++++ LICENSE | 204 ++++++++++++ packaging/coord.manifest | 5 + packaging/coord.rule | 8 + packaging/coord.spec | 88 +++++ service/CMakeLists.txt | 2 + service/dbus/CMakeLists.txt | 7 + service/dbus/org.tizen.system.coord.service | 5 + service/systemd/CMakeLists.txt | 11 + service/systemd/coord.service | 9 + src/backoff/backoff.c | 40 +++ src/core/common.h | 37 +++ src/core/coords.c | 76 +++++ src/core/coords.h | 89 ++++++ src/core/edbus-handler.c | 480 ++++++++++++++++++++++++++++ src/core/edbus-handler.h | 49 +++ src/core/list.h | 59 ++++ src/core/log.h | 53 +++ src/core/main.c | 60 ++++ src/rotation/rotation.c | 149 +++++++++ src/rotation/rotation.h | 56 ++++ src/rotation/setting.c | 89 ++++++ src/shared/dbus.c | 342 ++++++++++++++++++++ src/shared/dbus.h | 85 +++++ 25 files changed, 2093 insertions(+) create mode 100644 AUTHORS create mode 100755 CMakeLists.txt create mode 100644 LICENSE create mode 100644 packaging/coord.manifest create mode 100644 packaging/coord.rule create mode 100755 packaging/coord.spec create mode 100644 service/CMakeLists.txt create mode 100644 service/dbus/CMakeLists.txt create mode 100644 service/dbus/org.tizen.system.coord.service create mode 100644 service/systemd/CMakeLists.txt create mode 100644 service/systemd/coord.service create mode 100644 src/backoff/backoff.c create mode 100644 src/core/common.h create mode 100644 src/core/coords.c create mode 100644 src/core/coords.h create mode 100644 src/core/edbus-handler.c create mode 100644 src/core/edbus-handler.h create mode 100644 src/core/list.h create mode 100644 src/core/log.h create mode 100644 src/core/main.c create mode 100644 src/rotation/rotation.c create mode 100644 src/rotation/rotation.h create mode 100644 src/rotation/setting.c create mode 100644 src/shared/dbus.c create mode 100644 src/shared/dbus.h diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..5d726fd --- /dev/null +++ b/AUTHORS @@ -0,0 +1,4 @@ +Somin Kim +Yoonkyong Lee +Mu-Woong Lee +Kyoungjun Sung diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..38afe13 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,86 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(coord C) + +######################################################## +# Build options: +# -DMICRO_CD - for tizenw project +######################################################## +IF("$ENV{CFLAGS}" MATCHES "-DMICRO_CD") + OPTION(USE_MICRO_CD "Use Tizen Micro CD" ON) +ENDIF() + +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(EXEC_PREFIX "${PREFIX}/bin") +SET(LIBDIR "${PREFIX}/lib") +SET(INCLUDEDIR "${PREFIX}/include/${PROJECT_NAME}") +SET(DATADIR "${PREFIX}/share/${PROJECT_NAME}") +SET(LOCALEDIR "${PREFIX}/share/locale") +SET(VERSION 0.1.0) + +SET(SRCS + src/core/coords.c + src/core/main.c + src/core/edbus-handler.c + src/shared/dbus.c +) + +# back off +SET(SRCS ${SRCS} + src/backoff/backoff.c +) + +# rotation +SET(SRCS ${SRCS} + src/rotation/rotation.c +) +# rotation +SET(SRCS ${SRCS} + src/rotation/rotation.c +) + +IF(USE_MICRO_CD) +SET(SRCS ${SRCS} + src/rotation/setting.c +) +ENDIF(USE_MICRO_CD) + + + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) + +SET(PKG_MODULES + dlog + ecore + ecore-file + edbus + vconf +) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED ${PKG_MODULES}) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Werror") +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -g -fno-omit-frame-pointer -finstrument-functions") + +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -lrt") +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +MESSAGE("FLAGS: ${CMAKE_C_FLAGS}") + +ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"") +ADD_DEFINITIONS("-DLIBDIR=\"${LIBDIR}\"") + +ADD_DEFINITIONS("-DFEATURE_COORD_DLOG") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS} "-ldl") +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION sbin) + +INSTALL(FILES ${CMAKE_SOURCE_DIR}/packaging/${PROJECT_NAME}.rule DESTINATION /etc/smack/accesses2.d) + +INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE DESTINATION share/license RENAME ${PROJECT_NAME}) + +ADD_SUBDIRECTORY(service) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a06208b --- /dev/null +++ b/LICENSE @@ -0,0 +1,204 @@ +Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. + diff --git a/packaging/coord.manifest b/packaging/coord.manifest new file mode 100644 index 0000000..8521a02 --- /dev/null +++ b/packaging/coord.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/coord.rule b/packaging/coord.rule new file mode 100644 index 0000000..004460a --- /dev/null +++ b/packaging/coord.rule @@ -0,0 +1,8 @@ +# subject rule +coord sys-assert::core rwxat +coord system::vconf rwxat +coord system::vconf_system rw +coord telephony_framework::api_manager r +coord telephony_framework::api_modem wx +coord telephony_framework::api_private rwx + diff --git a/packaging/coord.spec b/packaging/coord.spec new file mode 100755 index 0000000..306e2cf --- /dev/null +++ b/packaging/coord.spec @@ -0,0 +1,88 @@ +Name: coord +Summary: coord +Version: 0.1.2 +Release: 1 +Group: Framework/system +License: Apache License, Version 2.0 +Source0: coord-%{version}.tar.gz +Source1001: coord.manifest + +BuildRequires: cmake +BuildRequires: libattr-devel +BuildRequires: gettext-devel +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(edbus) +BuildRequires: pkgconfig(sensor) +BuildRequires: pkgconfig(vconf) +BuildRequires: systemd-devel +BuildRequires: pkgconfig(systemd) + +Requires(preun): /usr/bin/systemctl +Requires(post): sys-assert +Requires(post): /usr/bin/systemctl +Requires(postun): /usr/bin/systemctl + +%description +coordination daemon + +%package coord +Summary: coord daemon +Group: main +Requires: %{name} = %{version}-%{release} + +%description coord +coordination daemon. + +%prep +%setup -q +%if 0%{?tizen_profile_wearable} +export CFLAGS+=" -DMICRO_CD" +%endif + +%if 0%{?tizen_build_binary_release_type_eng} +export CFLAGS+=" -DTIZEN_ENGINEER_MODE" +%endif +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + +%build +cp %{SOURCE1001} . +make + +%install +rm -rf %{buildroot} +%make_install + +# Enable coord.service. +# Use coord as system default launching daemon. +mkdir -p %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/ +ln -s ../coord.service %{buildroot}%{_libdir}/systemd/system/graphical.target.wants/ + +mkdir -p %{buildroot}%{_datadir}/license + +%post +systemctl daemon-reload +if [ $1 == 1 ]; then + systemctl restart coord.service +fi + +%preun +if [ $1 == 0 ]; then + systemctl stop coord.service +fi + +%postun +systemctl daemon-reload + + +%files -n coord +%{_sbindir}/coord +%{_libdir}/systemd/system/coord.service +%{_libdir}/systemd/system/graphical.target.wants/coord.service +%{_datadir}/dbus-1/services/org.tizen.system.coord.service +%{_datadir}/license/coord +%{_sysconfdir}/smack/accesses2.d/coord.rule + +%manifest coord.manifest + + diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt new file mode 100644 index 0000000..af86355 --- /dev/null +++ b/service/CMakeLists.txt @@ -0,0 +1,2 @@ +ADD_SUBDIRECTORY(systemd) +ADD_SUBDIRECTORY(dbus) diff --git a/service/dbus/CMakeLists.txt b/service/dbus/CMakeLists.txt new file mode 100644 index 0000000..38d16b8 --- /dev/null +++ b/service/dbus/CMakeLists.txt @@ -0,0 +1,7 @@ +SET(SYSTEM_DBUS_SERVICE_DIR "${PREFIX}/share/dbus-1/services") + +INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/org.tizen.system.coord.service + DESTINATION + ${SYSTEM_DBUS_SERVICE_DIR} +) diff --git a/service/dbus/org.tizen.system.coord.service b/service/dbus/org.tizen.system.coord.service new file mode 100644 index 0000000..2d3159f --- /dev/null +++ b/service/dbus/org.tizen.system.coord.service @@ -0,0 +1,5 @@ +[D-BUS Service] +Name=org.tizen.system.coord +Exec=/bin/false +SystemdService=coord.service +User=root diff --git a/service/systemd/CMakeLists.txt b/service/systemd/CMakeLists.txt new file mode 100644 index 0000000..6717add --- /dev/null +++ b/service/systemd/CMakeLists.txt @@ -0,0 +1,11 @@ +SET(SD_SYS_UNIT_DIR "${LIBDIR}/systemd/system") + +SET(SD_SYS_UNITS + coord.service +) + +INSTALL(FILES + ${CMAKE_CURRENT_BINARY_DIR}/${SD_SYS_UNITS} + DESTINATION + ${SD_SYS_UNIT_DIR} +) diff --git a/service/systemd/coord.service b/service/systemd/coord.service new file mode 100644 index 0000000..af58052 --- /dev/null +++ b/service/systemd/coord.service @@ -0,0 +1,9 @@ +[Unit] +Description=Start the coordination daemon service +After=graphical.target + +[Service] +Type=dbus +BusName=org.tizen.system.coord +ExecStart=/usr/sbin/coord +KillSignal=SIGUSR1 diff --git a/src/backoff/backoff.c b/src/backoff/backoff.c new file mode 100644 index 0000000..1faf911 --- /dev/null +++ b/src/backoff/backoff.c @@ -0,0 +1,40 @@ +/* + * coord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * 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 "core/log.h" +#include "core/coords.h" +#include "core/common.h" + +static void backoff_init(void *data) +{ + _D("init backoff"); +} + +static void backoff_exit(void *data) +{ + _D("exit backoff"); +} + +static const struct coord_ops backoff_coord_ops = { + .priority = COORD_PRIORITY_NORMAL, + .name = "backoff", + .init = backoff_init, + .exit = backoff_exit, +}; + +COORD_OPS_REGISTER(&backoff_coord_ops) diff --git a/src/core/common.h b/src/core/common.h new file mode 100644 index 0000000..00cff20 --- /dev/null +++ b/src/core/common.h @@ -0,0 +1,37 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 __CORE_COMMON_H__ +#define __CORE_COMMON_H__ + +#include +#include +#include + +#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0])) +#ifndef __CONSTRUCTOR__ +#define __CONSTRUCTOR__ __attribute__ ((constructor)) +#endif + +#ifndef __DESTRUCTOR__ +#define __DESTRUCTOR__ __attribute__ ((destructor)) +#endif + +#endif /* __CORE_COMMON_H__ */ + diff --git a/src/core/coords.c b/src/core/coords.c new file mode 100644 index 0000000..8724dd2 --- /dev/null +++ b/src/core/coords.c @@ -0,0 +1,76 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 "log.h" +#include "list.h" +#include "common.h" +#include "coords.h" + +static c_list *c_head; + +void add_coord(const struct coord_ops *c) +{ + if (c->priority == COORD_PRIORITY_HIGH) + C_LIST_PREPEND(c_head, c); + else + C_LIST_APPEND(c_head, c); +} + +void remove_coord(const struct coord_ops *c) +{ + C_LIST_REMOVE(c_head, c); +} + +const struct coord_ops *find_coord(const char *name) +{ + c_list *elem; + const struct coord_ops *c; + + C_LIST_FOREACH(c_head, elem, c) { + if (!strcmp(c->name, name)) + return c; + } + return NULL; +} + +void coords_init(void *data) +{ + c_list *elem; + const struct coord_ops *c; + + C_LIST_FOREACH(c_head, elem, c) { + _D("[%s] initialize", c->name); + if (c->init) + c->init(data); + } +} + +void coords_exit(void *data) +{ + c_list *elem; + const struct coord_ops *c; + + C_LIST_FOREACH(c_head, elem, c) { + _D("[%s] deinitialize", c->name); + if (c->exit) + c->exit(data); + } +} diff --git a/src/core/coords.h b/src/core/coords.h new file mode 100644 index 0000000..15d24f6 --- /dev/null +++ b/src/core/coords.h @@ -0,0 +1,89 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 __COORDS_H__ +#define __COORDS_H__ + +#include +#include "common.h" + +enum coord_priority { + COORD_PRIORITY_NORMAL = 0, + COORD_PRIORITY_HIGH, +}; + +struct coord_ops { + enum coord_priority priority; + char *name; + void (*init) (void *data); + void (*exit) (void *data); + int (*start) (void); + int (*stop) (void); + int (*status) (void); +}; + +enum coord_ops_status { + COORD_OPS_STATUS_UNINIT, + COORD_OPS_STATUS_START, + COORD_OPS_STATUS_STOP, + COORD_OPS_STATUS_MAX, +}; + +void coords_init(void *data); +void coords_exit(void *data); + +static inline int coord_start(const struct coord_ops *c) +{ + if (c && c->start) + return c->start(); + + return -EINVAL; +} + +static inline int coord_stop(const struct coord_ops *c) +{ + if (c && c->stop) + return c->stop(); + + return -EINVAL; +} + +static inline int coord_get_status(const struct coord_ops *c) +{ + if (c && c->status) + return c->status(); + + return -EINVAL; +} + +#define COORD_OPS_REGISTER(c) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_coord(c); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_coord(c); \ +} + +void add_coord(const struct coord_ops *c); +void remove_coord(const struct coord_ops *c); +const struct coord_ops *find_coord(const char *name); + +#endif diff --git a/src/core/edbus-handler.c b/src/core/edbus-handler.c new file mode 100644 index 0000000..7f928ca --- /dev/null +++ b/src/core/edbus-handler.c @@ -0,0 +1,480 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 "core/log.h" +#include "core/edbus-handler.h" +#include "core/common.h" +#include "core/list.h" + +#define EDBUS_INIT_RETRY_COUNT 5 + +/* -1 is a default timeout value, it's converted to 25*1000 internally. */ +#define DBUS_REPLY_TIMEOUT (-1) +#define RETRY_MAX 5 + +struct edbus_list{ + char *signal_name; + char *interface_name; + E_DBus_Signal_Cb cb; + E_DBus_Signal_Handler *handler; +}; + +static struct edbus_object { + const char *path; + const char *interface; + E_DBus_Object *obj; + E_DBus_Interface *iface; +} edbus_objects[] = { + { COORD_PATH_ROTATION , COORD_INTERFACE_ROTATION , NULL, NULL }, + /* Add new object & interface here*/ +}; + +static c_list *edbus_handler_list; +static int edbus_init_val; +static DBusConnection *conn; +static E_DBus_Connection *edbus_conn; +static DBusPendingCall *edbus_request_name; + +static int register_edbus_interface(struct edbus_object *object) +{ + int ret; + + if (!object) { + _E("object is invalid value!"); + return -1; + } + + object->obj = e_dbus_object_add(edbus_conn, object->path, NULL); + if (!object->obj) { + _E("fail to add edbus obj"); + return -1; + } + + object->iface = e_dbus_interface_new(object->interface); + if (!object->iface) { + _E("fail to add edbus interface"); + e_dbus_object_free(object->obj); + object->obj = NULL; + return -1; + } + + e_dbus_object_interface_attach(object->obj, object->iface); + + return 0; +} + +static int unregister_edbus_interface(struct edbus_object *object) +{ + int ret; + + if (!object) { + _E("object is invalid value!"); + return -1; + } + + if (object->iface) { + e_dbus_object_interface_detach(object->obj, object->iface); + e_dbus_interface_unref(object->iface); + object->iface = NULL; + } + + if (object->obj) { + e_dbus_object_free(object->obj); + object->obj = NULL; + } + + return 0; +} + +E_DBus_Interface *get_edbus_interface(const char *path) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) + if (!strcmp(path, edbus_objects[i].path)) + return edbus_objects[i].iface; + + return NULL; +} + +pid_t get_edbus_sender_pid(DBusMessage *msg) +{ + const char *sender; + DBusMessage *send_msg; + DBusPendingCall *pending; + DBusMessageIter iter; + int ret; + pid_t pid; + + if (!msg) { + _E("invalid argument!"); + return -1; + } + + sender = dbus_message_get_sender(msg); + if (!sender) { + _E("invalid sender!"); + return -1; + } + + send_msg = dbus_message_new_method_call(DBUS_SERVICE_DBUS, + DBUS_PATH_DBUS, + DBUS_INTERFACE_DBUS, + "GetConnectionUnixProcessID"); + if (!send_msg) { + _E("invalid send msg!"); + return -1; + } + + ret = dbus_message_append_args(send_msg, DBUS_TYPE_STRING, + &sender, DBUS_TYPE_INVALID); + if (!ret) { + _E("fail to append args!"); + dbus_message_unref(send_msg); + return -1; + } + + pending = e_dbus_message_send(edbus_conn, send_msg, NULL, -1, NULL); + if (!pending) { + _E("pending is null!"); + dbus_message_unref(send_msg); + return -1; + } + + dbus_message_unref(send_msg); + + /* block until reply is received */ + dbus_pending_call_block(pending); + + msg = dbus_pending_call_steal_reply(pending); + dbus_pending_call_unref(pending); + if (!msg) { + _E("reply msg is null!"); + return -1; + } + + dbus_message_iter_init(msg, &iter); + dbus_message_iter_get_basic(&iter, &pid); + dbus_message_unref(msg); + + return pid; +} + +static void unregister_edbus_signal_handle(void) +{ + c_list *tmp; + struct edbus_list *entry; + + C_LIST_FOREACH(edbus_handler_list, tmp, entry) { + if (entry != NULL) { + e_dbus_signal_handler_del(edbus_conn, entry->handler); + C_LIST_REMOVE(edbus_handler_list, entry); + free(entry->signal_name); + free(entry); + } + } +} + +int unregister_edbus_signal_handler(const char *interface, const char *name, E_DBus_Signal_Cb cb) +{ + c_list *tmp; + struct edbus_list *entry; + E_DBus_Signal_Handler *handler; + + C_LIST_FOREACH(edbus_handler_list, tmp, entry) { + if (entry != NULL && strncmp(entry->signal_name, name, strlen(name)) == 0 + && strncmp(entry->interface_name, interface, strlen(interface)) == 0 + && entry->cb == cb) { + e_dbus_signal_handler_del(edbus_conn, entry->handler); + C_LIST_REMOVE(edbus_handler_list, entry); + free(entry->signal_name); + free(entry->interface_name); + free(entry); + return 0; + } + } + + return -ENOENT; +} + +int register_edbus_signal_handler(const char *path, const char *interface, + const char *name, E_DBus_Signal_Cb cb) +{ + c_list *tmp; + struct edbus_list *entry; + E_DBus_Signal_Handler *handler; + + C_LIST_FOREACH(edbus_handler_list, tmp, entry) { + if (entry != NULL && strncmp(entry->signal_name, name, strlen(name)) == 0 + && entry->cb == cb) + return -EEXIST; + } + + handler = e_dbus_signal_handler_add(edbus_conn, NULL, path, + interface, name, cb, NULL); + + if (!handler) { + _E("fail to add edbus handler"); + return -ENOMEM; + } + + entry = malloc(sizeof(struct edbus_list)); + + if (!entry) { + _E("Malloc failed"); + return -ENOMEM; + } + + entry->signal_name = strndup(name, strlen(name)); + + if (!entry->signal_name) { + _E("Malloc failed"); + free(entry); + return -ENOMEM; + } + + entry->interface_name = strndup(interface, strlen(interface)); + + if (!entry->interface_name) { + _E("Malloc failed"); + free(entry->signal_name); + free(entry); + return -ENOMEM; + } + + entry->handler = handler; + entry->cb = cb; + C_LIST_PREPEND(edbus_handler_list, entry); + if (!edbus_handler_list) { + _E("eina_list_prepend failed"); + free(entry->signal_name); + free(entry->interface_name); + free(entry); + return -ENOMEM; + } + return 0; +} + +int broadcast_edbus_signal(const char *path, const char *interface, + const char *name, const char *sig, char *param[]) +{ + DBusMessage *msg; + DBusMessageIter iter; + int r; + + msg = dbus_message_new_signal(path, interface, name); + if (!msg) { + _E("fail to allocate new %s.%s signal", interface, name); + return -EPERM; + } + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, sig, param); + if (r < 0) { + _E("append_variant error(%d)", r); + return -EPERM; + } + + e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL); + + dbus_message_unref(msg); + return 0; +} + +int send_edbus_message(const char* dest, const char *path, const char *interface, + const char *method, const char *sig, char *param[]) +{ + DBusMessage *msg; + DBusMessageIter iter; + int r; + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("fail to allocate new %s.%s message", interface, method); + return -EPERM; + } + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, sig, param); + if (r < 0) { + _E("append_variant error(%d)", r); + return -EPERM; + } + + e_dbus_message_send(edbus_conn, msg, NULL, -1, NULL); + + dbus_message_unref(msg); + return 0; +} + +void register_edbus_method_handler(const char* dest, const char* path, const char* interface, + const char* method, E_DBus_Method_Return_Cb cb) +{ + DBusMessage *msg = NULL; + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("Failed: dbus_message_new_method_call()"); + } + + e_dbus_message_send(edbus_conn, msg, cb, DBUS_REPLY_TIMEOUT, NULL); + + dbus_message_unref(msg); +} + +int register_edbus_method(const char *path, const struct edbus_method *edbus_methods, int size) +{ + E_DBus_Interface *iface; + int ret; + int i; + + iface = get_edbus_interface(path); + + if (!iface) { + _E("fail to get edbus interface!"); + return -ENODEV; + } + + for (i = 0; i < size; i++) { + ret = e_dbus_interface_method_add(iface, + edbus_methods[i].member, + edbus_methods[i].signature, + edbus_methods[i].reply_signature, + edbus_methods[i].func); + if (!ret) { + _E("fail to add method %s!", edbus_methods[i].member); + return -EINVAL; + } + } + + return 0; +} + +static void request_name_cb(void *data, DBusMessage *msg, DBusError *error) +{ + DBusError err; + unsigned int val; + int r; + + if (!msg) { + _D("invalid DBusMessage!"); + return; + } + + dbus_error_init(&err); + r = dbus_message_get_args(msg, &err, DBUS_TYPE_UINT32, &val, DBUS_TYPE_INVALID); + if (!r) { + _E("no message : [%s:%s]", err.name, err.message); + dbus_error_free(&err); + return; + } + + _I("Request Name reply : %d", val); +} + +void edbus_init(void *data) +{ + DBusError error; + int retry = 0; + int i, ret; + + dbus_threads_init_default(); + dbus_error_init(&error); + + do { + edbus_init_val = e_dbus_init(); + if (edbus_init_val) + break; + if (retry == EDBUS_INIT_RETRY_COUNT) { + _E("fail to init edbus"); + return; + } + retry++; + } while (retry <= EDBUS_INIT_RETRY_COUNT); + + retry = 0; + do { + edbus_conn = e_dbus_bus_get(DBUS_BUS_SYSTEM); + if (edbus_conn) + break; + if (retry == EDBUS_INIT_RETRY_COUNT) { + _E("fail to get edbus"); + return; + } + retry++; + } while (retry <= EDBUS_INIT_RETRY_COUNT); + + retry = 0; + do { + edbus_request_name = e_dbus_request_name(edbus_conn, COORD_BUS_NAME, + DBUS_NAME_FLAG_REPLACE_EXISTING, request_name_cb, NULL); + if (edbus_request_name) + break; + if (retry == EDBUS_INIT_RETRY_COUNT) { + _E("fail to request edbus name"); + goto out1; + } + retry++; + } while (retry <= EDBUS_INIT_RETRY_COUNT); + + for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) { + ret = register_edbus_interface(&edbus_objects[i]); + if (ret < 0) { + _E("fail to add obj & interface for %s", + edbus_objects[i].interface); + goto out2; + } + _D("add new obj for %s", edbus_objects[i].interface); + } + return; + +out2: + e_dbus_release_name(edbus_conn, COORD_BUS_NAME, request_name_cb, NULL); +out1: + e_dbus_connection_close(edbus_conn); + edbus_conn = NULL; + e_dbus_shutdown(); +} + +void edbus_exit(void *data) +{ + if(!edbus_conn) + return; + + int i, ret; + + unregister_edbus_signal_handle(); + + for (i = 0; i < ARRAY_SIZE(edbus_objects); i++) { + ret = unregister_edbus_interface(&edbus_objects[i]); + if (ret < 0) { + _E("fail to delete obj & interface for %s", + edbus_objects[i].interface); + } + _D("add new obj for %s", edbus_objects[i].interface); + } + + e_dbus_release_name(edbus_conn, COORD_BUS_NAME, request_name_cb, NULL); + + e_dbus_connection_close(edbus_conn); + edbus_conn = NULL; + + e_dbus_shutdown(); +} diff --git a/src/core/edbus-handler.h b/src/core/edbus-handler.h new file mode 100644 index 0000000..449bc03 --- /dev/null +++ b/src/core/edbus-handler.h @@ -0,0 +1,49 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 __EDBUS_HANDLE_H__ +#define __EDBUS_HANDLE_H__ + +#include +#include "shared/dbus.h" + +struct edbus_method { + const char *member; + const char *signature; + const char *reply_signature; + E_DBus_Method_Cb func; +}; + +int register_edbus_method(const char *path, const struct edbus_method *edbus_methods, int size); +int unregister_edbus_signal_handler(const char *interface, const char *name, E_DBus_Signal_Cb cb); +int register_edbus_signal_handler(const char *path, const char *interface, + const char *name, E_DBus_Signal_Cb cb); +void register_edbus_method_handler(const char *dest, const char *path, const char *interface, + const char *method, E_DBus_Method_Return_Cb cb); +E_DBus_Interface *get_edbus_interface(const char *path); +pid_t get_edbus_sender_pid(DBusMessage *msg); +int send_edbus_message(const char* dest, const char *path, const char *interface, + const char *method, const char *sig, char *param[]); +int broadcast_edbus_signal(const char *path, const char *interface, + const char *name, const char *sig, char *param[]); + +void edbus_init(void *data); +void edbus_exit(void *data); + +#endif /* __EDBUS_HANDLE_H__ */ diff --git a/src/core/list.h b/src/core/list.h new file mode 100644 index 0000000..ad08226 --- /dev/null +++ b/src/core/list.h @@ -0,0 +1,59 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. All rights reserved. + * + * 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 __LIST_H__ +#define __LIST_H__ + +#include + +#ifdef EINA_LIST +typedef Eina_List c_list; +#define C_LIST_PREPEND(a, b) \ + a = eina_list_prepend(a, b) +#define C_LIST_APPEND(a, b) \ + a = eina_list_append(a, b) +#define C_LIST_REMOVE(a, b) \ + a = eina_list_remove(a, b) +#define C_LIST_LENGTH(a) \ + eina_list_count(a) +#define C_LIST_NTH(a, b) \ + eina_list_nth(a, b) +#define C_LIST_FREE_LIST(a) \ + a = eina_list_free(a) +#define C_LIST_FOREACH(head, elem, node) \ + EINA_LIST_FOREACH(head, elem, node) +#else +#include +typedef GList c_list; +#define C_LIST_PREPEND(a, b) \ + a = g_list_prepend(a, (gpointer)b) +#define C_LIST_APPEND(a, b) \ + a = g_list_append(a, (gpointer)b) +#define C_LIST_REMOVE(a, b) \ + a = g_list_remove(a, (gpointer)b) +#define C_LIST_LENGTH(a) \ + g_list_length(a) +#define C_LIST_NTH(a, b) \ + g_list_nth_data(a, b) +#define C_LIST_FREE_LIST(a) \ + g_list_free(a) +#define C_LIST_FOREACH(head, elem, node) \ + for (elem = head, node = NULL; elem && ((node = elem->data) != NULL); elem = elem->next, node = NULL) +#endif + +#endif diff --git a/src/core/log.h b/src/core/log.h new file mode 100644 index 0000000..1b3452a --- /dev/null +++ b/src/core/log.h @@ -0,0 +1,53 @@ +/* + * coord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * 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 __LOG_H__ +#define __LOG_H__ + +#ifdef FEATURE_COORD_DLOG +#define LOG_TAG "COORD" +#include +#define _D(fmt, arg...) \ + do { SLOGD(fmt, ##arg); } while(0) +#define _I(fmt, arg...) \ + do { SLOGI(fmt, ##arg); } while(0) +#define _W(fmt, arg...) \ + do { SLOGW(fmt, ##arg); } while(0) +#define _E(fmt, arg...) \ + do { SLOGE(fmt, ##arg); } while(0) +#define _SD(fmt, arg...) \ + do { SECURE_SLOGD(fmt, ##arg); } while(0) +#define _SI(fmt, arg...) \ + do { SECURE_SLOGI(fmt, ##arg); } while(0) +#define _SW(fmt, arg...) \ + do { SECURE_SLOGW(fmt, ##arg); } while(0) +#define _SE(fmt, arg...) \ + do { SECURE_SLOGE(fmt, ##arg); } while(0) +#else +#define _D(x, ...) do { } while (0) +#define _I(x, ...) do { } while (0) +#define _W(x, ...) do { } while (0) +#define _E(x, ...) do { } while (0) +#define _SD(fmt, args...) do { } while (0) +#define _SI(fmt, args...) do { } while (0) +#define _SW(fmt, args...) do { } while (0) +#define _SE(fmt, args...) do { } while (0) +#endif + +#endif diff --git a/src/core/main.c b/src/core/main.c new file mode 100644 index 0000000..f9d8cef --- /dev/null +++ b/src/core/main.c @@ -0,0 +1,60 @@ +/* + * coord + * + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * 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 +#include + +#include "log.h" +#include "coords.h" + +static void sig_quit(int signo) +{ + _D("received SIGTERM signal %d", signo); +} + +static void sig_usr1(int signo) +{ + _D("received SIGUSR1 signal %d, coord will be finished!", signo); + + ecore_main_loop_quit(); +} + +static int coord_main(int argc, char **argv) +{ + edbus_init((void *)NULL); + coords_init((void *)NULL); + + signal(SIGTERM, sig_quit); + signal(SIGUSR1, sig_usr1); + + ecore_main_loop_begin(); + + coords_exit((void *)NULL); + edbus_exit((void *)NULL); + ecore_shutdown(); + return 0; +} + +int main(int argc, char **argv) +{ + ecore_init(); + return coord_main(argc, argv); +} + diff --git a/src/rotation/rotation.c b/src/rotation/rotation.c new file mode 100644 index 0000000..2d45a7b --- /dev/null +++ b/src/rotation/rotation.c @@ -0,0 +1,149 @@ +/* + * coord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include "core/log.h" +#include "core/list.h" +#include "core/common.h" +#include "core/coords.h" +#include "core/edbus-handler.h" +#include "shared/dbus.h" +#include "rotation.h" + +#define CHECK_VALID_OPS(ops, r) ((ops) ? true : !(r = -ENODEV)) + +/* rotation operation variable */ +static c_list *r_head; +static const struct rotation_profile_ops *r_ops; + +void add_rotation(const struct rotation_ops *ops) { + C_LIST_APPEND(r_head, (void*)ops); +} + +void remove_rotation(const struct rotation_ops *ops) { + C_LIST_REMOVE(r_head, (void*)ops); +} + +int broadcast_rotation_status(int last_notified_status) { + int r, rot; + char *arr[1]; + char str_status[32]; + + rot = r_ops->get_rotation_status(); + + if (last_notified_status == rot) { + return rot; + } + + snprintf(str_status, sizeof(str_status), "%d", rot); + arr[0] = str_status; + r = broadcast_edbus_signal(COORD_PATH_ROTATION, COORD_INTERFACE_ROTATION, + COORD_SIGNAL_ROTATION_CHANGED, "i", arr); + _D("broadcast rotation signal: %d", rot); + if (r < 0) { + _E("Failed: broadcast_edbus_signal()"); + return last_notified_status; + } + + return rot; +} + +static DBusMessage *edbus_get_degree(E_DBus_Object *obj, DBusMessage *message) +{ + DBusMessageIter iter; + DBusMessage* reply; + int r, rot; + + if (!CHECK_VALID_OPS(r_ops, r)) + goto exit; + + rot = r_ops->get_rotation_status(); + r = rot; + +exit: + reply = dbus_message_new_method_return(message); + dbus_message_iter_init_append(reply, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_INT32, &r); + return reply; +} + +static const struct edbus_method edbus_methods[] = { + { COORD_METHOD_ROTATION_DEGREE, NULL, NULL, edbus_get_degree }, + /* Add methods here */ +}; + +static void rotation_init(void *data) +{ + _D("init rotation"); + + struct rotation_ops *ops; + c_list *elem; + int r; + + /* find valid profile */ + C_LIST_FOREACH(r_head, elem, ops) { + if (ops->load) + r_ops = ops->load(); + break; + } + + if (!CHECK_VALID_OPS(r_ops, r)) { + _E("Can't find the valid rotation profile"); + return; + } + + /* init dbus interface */ + r = register_edbus_method(COORD_PATH_ROTATION, edbus_methods, ARRAY_SIZE(edbus_methods)); + if (r < 0) { + _E("fail to init edbus method(%d)", r); + return; + } +} + +static void rotation_exit(void *data) +{ + _D("exit rotation"); + + struct rotation_ops *ops; + c_list *elem; + int r; + + if (!CHECK_VALID_OPS(r_ops, r)) + return; + + /* release profile */ + C_LIST_FOREACH(r_head, elem, ops) { + if (ops->release) + ops->release(); + r_ops = NULL; + break; + } + +} + +static const struct coord_ops rotation_coord_ops = { + .priority = COORD_PRIORITY_NORMAL, + .name = "rotation", + .init = rotation_init, + .exit = rotation_exit, +}; + +COORD_OPS_REGISTER(&rotation_coord_ops) + diff --git a/src/rotation/rotation.h b/src/rotation/rotation.h new file mode 100644 index 0000000..7bcd9f7 --- /dev/null +++ b/src/rotation/rotation.h @@ -0,0 +1,56 @@ +/* + * coord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * 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 __ROTATION_H__ +#define __ROTATION_H__ + +#include "core/common.h" + +#define ROTATION_OPS_REGISTER(dev) \ +static void __CONSTRUCTOR__ module_init(void) \ +{ \ + add_rotation(dev); \ +} \ +static void __DESTRUCTOR__ module_exit(void) \ +{ \ + remove_rotation(dev); \ +} + +struct rotation_profile_ops { + int (*get_rotation_status)(void); +}; + +struct rotation_ops { + const struct rotation_profile_ops *(*load)(void); + void (*release)(void); +}; + +enum rotation_status { + COORD_ROTATION_UNKNOWN = 0, // ROTATION_UNKNOWN + COORD_ROTATION_LANDSCAPE_LEFT = 1, // ROTATION_LANDSCAPE_LEFT (90) + COORD_ROTATION_PORTRAIT_TOP = 2, // ROTATION_PORTRAIT_TOP (0) + COORD_ROTATION_PORTRAIT_BOTTOM = 3, // ROTATION_PORTRAIT_BOTTOM (180) + COORD_ROTATION_LANDSCAPE_RIGHT = 4, // ROTATION_LANDSCAPE_RIGHT (270) +}; + +void add_rotation(const struct rotation_ops *ops); +void remove_rotation(const struct rotation_ops *ops); +int broadcast_rotation_status(int last_notified_status); + +#endif diff --git a/src/rotation/setting.c b/src/rotation/setting.c new file mode 100644 index 0000000..cd3a5c9 --- /dev/null +++ b/src/rotation/setting.c @@ -0,0 +1,89 @@ +/* + * coord + * + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include +#include "core/log.h" +#include "core/common.h" +#include "core/edbus-handler.h" +#include "shared/dbus.h" +#include "rotation.h" + +/* Micro Rotation Logic */ +static int get_rotation_status(); +static void broadcast_micro_rotation_status(); + +/* Device Status */ +static struct _device_status { + int fixed_rotation; +} device_status = {COORD_ROTATION_PORTRAIT_TOP}; + +/* Not used in here */ +/* +static int get_contextd2coord_rotation_status(int rot) +{ + switch(rot) { + case 0: + return COORD_ROTATION_PORTRAIT_TOP; + case 3: + return COORD_ROTATION_LANDSCAPE_RIGHT; + case 2: + return COORD_ROTATION_PORTRAIT_BOTTOM; + case 1: + return COORD_ROTATION_LANDSCAPE_LEFT; + default: + return COORD_ROTATION_UNKNOWN; + } +} +*/ + +void broadcast_micro_rotation_status() +{ + static int last_notified_status = COORD_ROTATION_UNKNOWN; + + int rot = broadcast_rotation_status(last_notified_status); + last_notified_status = rot; +} + +int get_rotation_status() +{ + return device_status.fixed_rotation; +} + +static const struct rotation_profile_ops micro_profile = { + .get_rotation_status = get_rotation_status, +}; + +static const struct rotation_profile_ops *load(void) { + + return µ_profile; +} + +static void release(void) { + + return; +} + +static const struct rotation_ops micro_ops = { + .load = load, + .release = release, +}; + +ROTATION_OPS_REGISTER(µ_ops); diff --git a/src/shared/dbus.c b/src/shared/dbus.c new file mode 100644 index 0000000..f315487 --- /dev/null +++ b/src/shared/dbus.c @@ -0,0 +1,342 @@ +/* + * coord + * + * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. + * + * 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 +#include +#include + +#include "core/common.h" +#include "core/log.h" +#include "dbus.h" + +/* -1 is a default timeout value, it's converted to 25*1000 internally. */ +#define DBUS_REPLY_TIMEOUT (-1) + +struct pending_call_data { + dbus_pending_cb func; + void *data; +}; + +int append_variant(DBusMessageIter *iter, const char *sig, char *param[]) +{ + char *ch; + int i; + int int_type; + uint64_t int64_type; + DBusMessageIter arr; + struct dbus_byte *byte; + + if (!sig || !param) + return 0; + + for (ch = (char*)sig, i = 0; *ch != '\0'; ++i, ++ch) { + switch (*ch) { + case 'i': + int_type = atoi(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_INT32, &int_type); + break; + case 'u': + int_type = strtoul(param[i], NULL, 10); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &int_type); + break; + case 't': + int64_type = atoll(param[i]); + dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT64, &int64_type); + break; + case 's': + dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING, ¶m[i]); + break; + case 'a': + ++i, ++ch; + switch (*ch) { + case 'y': + dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &arr); + byte = (struct dbus_byte*)param[i]; + dbus_message_iter_append_fixed_array(&arr, DBUS_TYPE_BYTE, &(byte->data), byte->size); + dbus_message_iter_close_container(iter, &arr); + break; + default: + break; + } + break; + default: + return -EINVAL; + } + } + + return 0; +} + +DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + int r; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + _E("dbus_bus_get error"); + return NULL; + } + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", + path, interface, method); + return NULL; + } + + dbus_message_iter_init_append(msg, &iter); + r = append_variant(&iter, sig, param); + if (r < 0) { + _E("append_variant error(%d) %s %s:%s-%s", + r, dest, path, interface, method); + dbus_message_unref(msg); + return NULL; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err); + if (!reply) { + _E("dbus_connection_send error(No reply) %s %s:%s-%s", + dest, path, interface, method); + } + + if (dbus_error_is_set(&err)) { + _E("dbus_connection_send error(%s:%s) %s %s:%s-%s", + err.name, err.message, dest, path, interface, method); + dbus_error_free(&err); + reply = NULL; + } + + dbus_message_unref(msg); + return reply; +} + +int dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusMessage *reply; + DBusError err; + int ret, result; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + _E("dbus_bus_get error"); + return -EPERM; + } + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", + path, interface, method); + return -EBADMSG; + } + + dbus_message_iter_init_append(msg, &iter); + ret = append_variant(&iter, sig, param); + if (ret < 0) { + _E("append_variant error(%d) %s %s:%s-%s", + ret, dest, path, interface, method); + dbus_message_unref(msg); + return ret; + } + + dbus_error_init(&err); + + reply = dbus_connection_send_with_reply_and_block(conn, msg, DBUS_REPLY_TIMEOUT, &err); + dbus_message_unref(msg); + if (!reply) { + _E("dbus_connection_send error(%s:%s) %s %s:%s-%s", + err.name, err.message, dest, path, interface, method); + dbus_error_free(&err); + return -ECOMM; + } + + ret = dbus_message_get_args(reply, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID); + dbus_message_unref(reply); + if (!ret) { + _E("no message : [%s:%s] %s %s:%s-%s", + err.name, err.message, dest, path, interface, method); + dbus_error_free(&err); + return -ENOMSG; + } + + return result; +} + +int dbus_method_async(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + int ret; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + _E("dbus_bus_get error"); + return -EPERM; + } + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", + path, interface, method); + return -EBADMSG; + } + + dbus_message_iter_init_append(msg, &iter); + ret = append_variant(&iter, sig, param); + if (ret < 0) { + _E("append_variant error(%d) %s %s:%s-%s", + ret, dest, path, interface, method); + dbus_message_unref(msg); + return ret; + } + + ret = dbus_connection_send(conn, msg, NULL); + dbus_message_unref(msg); + if (ret != TRUE) { + _E("dbus_connection_send error(%s %s:%s-%s)", + dest, path, interface, method); + return -ECOMM; + } + + return 0; +} + +static void cb_pending(DBusPendingCall *pending, void *user_data) +{ + DBusMessage *msg; + DBusError err; + struct pending_call_data *data = user_data; + int ret; + + ret = dbus_pending_call_get_completed(pending); + if (!ret) { + _I("dbus_pending_call_get_completed() fail"); + free(data); + dbus_pending_call_unref(pending); + return; + } + + dbus_error_init(&err); + msg = dbus_pending_call_steal_reply(pending); + if (!msg) { + if (data->func) { + dbus_set_error(&err, "org.tizen.system.deviced.NoReply", + "There was no reply to this method call"); + data->func(data->data, NULL, &err); + dbus_error_free(&err); + } + return; + } + + ret = dbus_set_error_from_message(&err, msg); + if (ret) { + if (data->func) + data->func(data->data, NULL, &err); + dbus_error_free(&err); + } else { + if (data->func) + data->func(data->data, msg, &err); + } + + dbus_message_unref(msg); + dbus_pending_call_unref(pending); +} + +int dbus_method_async_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data) +{ + DBusConnection *conn; + DBusMessage *msg; + DBusMessageIter iter; + DBusPendingCall *pending = NULL; + struct pending_call_data *pdata; + int ret; + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (!conn) { + _E("dbus_bus_get error"); + return -EPERM; + } + + msg = dbus_message_new_method_call(dest, path, interface, method); + if (!msg) { + _E("dbus_message_new_method_call(%s:%s-%s)", + path, interface, method); + return -EBADMSG; + } + + dbus_message_iter_init_append(msg, &iter); + ret = append_variant(&iter, sig, param); + if (ret < 0) { + _E("append_variant error(%d)%s %s:%s-%s", + ret, dest, path, interface, method); + dbus_message_unref(msg); + return ret; + } + + ret = dbus_connection_send_with_reply(conn, msg, &pending, timeout); + if (!ret) { + dbus_message_unref(msg); + _E("dbus_connection_send error(%s %s:%s-%s)", + dest, path, interface, method); + return -ECOMM; + } + + if (cb && pending) { + pdata = malloc(sizeof(struct pending_call_data)); + if (!pdata) + return -ENOMEM; + + pdata->func = cb; + pdata->data = data; + + ret = dbus_pending_call_set_notify(pending, cb_pending, pdata, free); + if (!ret) { + free(pdata); + dbus_message_unref(msg); + dbus_pending_call_cancel(pending); + return -ECOMM; + } + } + + return 0; +} + +static void __CONSTRUCTOR__ dbus_init(void) +{ + dbus_threads_init_default(); +} diff --git a/src/shared/dbus.h b/src/shared/dbus.h new file mode 100644 index 0000000..db22c19 --- /dev/null +++ b/src/shared/dbus.h @@ -0,0 +1,85 @@ +/* + * coord + * + * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. + * + * 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 __DBUS_H__ +#define __DBUS_H__ + +#include + +/* + * Template + * +#define XXX_BUS_NAME "org.tizen.system.XXX" +#define XXX_OBJECT_PATH "/Org/Tizen/System/XXX" +#define XXX_INTERFACE_NAME XXX_BUS_NAME +#define XXX_PATH_YYY XXX_OBJECT_PATH"/YYY" +#define XXX_INTERFACE_YYY XXX_INTERFACE_NAME".YYY" +#define XXX_SIGNAL_ZZZ "ZZZ" +#define XXX_METHOD_ZZZ "ZZZ" + */ + +/* + * Coordinator daemon + */ +#define COORD_BUS_NAME "org.tizen.system.coord" +#define COORD_OBJECT_PATH "/Org/Tizen/System/Coord" +#define COORD_INTERFACE_NAME COORD_BUS_NAME +/* Rotation service: operations about rotation */ +#define COORD_PATH_ROTATION COORD_OBJECT_PATH"/Rotation" +#define COORD_INTERFACE_ROTATION COORD_INTERFACE_NAME".rotation" +#define COORD_SIGNAL_ROTATION_CHANGED "Changed" +#define COORD_METHOD_ROTATION_DEGREE "Degree" + +/* + * Context daemon + */ +#define CONTEXTD_BUS_NAME "org.tizen.sensor.context" +#define CONTEXTD_OBJECT_PATH "/org/tizen/sensor/context" +#define CONTEXTD_INTERFACE_NAME CONTEXTD_BUS_NAME +/* Rotation */ +#define CONTEXTD_PATH_ROTATION CONTEXTD_OBJECT_PATH"/rotation" +#define CONTEXTD_INTERFACE_ROTATION CONTEXTD_INTERFACE_NAME".rotation" +#define CONTEXTD_SIGNAL_CHANGED "Changed" +#define CONTEXTD_METHOD_SET "Set" + +struct dbus_byte { + const char *data; + int size; +}; + +int append_variant(DBusMessageIter *iter, const char *sig, char *param[]); + +DBusMessage *dbus_method_sync_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]); + +int dbus_method_sync(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]); + +int dbus_method_async(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[]); + +typedef void (*dbus_pending_cb)(void *data, DBusMessage *msg, DBusError *err); + +int dbus_method_async_with_reply(const char *dest, const char *path, + const char *interface, const char *method, + const char *sig, char *param[], dbus_pending_cb cb, int timeout, void *data); +#endif -- 2.7.4