diff options
author | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:00:35 +0900 |
---|---|---|
committer | HyungKyu Song <hk76.song@samsung.com> | 2013-02-16 00:00:35 +0900 |
commit | 479b16d56288110cd6f96808b09093a1e6a7e083 (patch) | |
tree | a220ba6e26085335bc28f318e563858faadc256c | |
parent | 51c6a1be576b2bf51544a96c6f43f7a73659b446 (diff) | |
download | menu-daemon-479b16d56288110cd6f96808b09093a1e6a7e083.tar.gz menu-daemon-479b16d56288110cd6f96808b09093a1e6a7e083.tar.bz2 menu-daemon-479b16d56288110cd6f96808b09093a1e6a7e083.zip |
-rwxr-xr-x | CMakeLists.txt | 54 | ||||
-rw-r--r-- | LICENSE | 75 | ||||
-rw-r--r-- | NOTICE | 0 | ||||
-rw-r--r-- | data/CMakeLists.txt | 7 | ||||
-rwxr-xr-x | data/menudaemon | 4 | ||||
-rwxr-xr-x | data/menudaemon.fast | 3 | ||||
-rw-r--r-- | debian/changelog | 44 | ||||
-rw-r--r-- | debian/compat | 1 | ||||
-rwxr-xr-x | debian/control | 19 | ||||
-rw-r--r-- | debian/copyright | 0 | ||||
-rw-r--r-- | debian/jobs | 0 | ||||
-rw-r--r-- | debian/menu-daemon.install.in | 2 | ||||
-rwxr-xr-x | debian/menu-daemon.postinst | 13 | ||||
-rwxr-xr-x | debian/rules | 133 | ||||
-rw-r--r-- | include/desktop_to_db.h | 73 | ||||
-rw-r--r-- | include/hw_key.h | 24 | ||||
-rw-r--r-- | include/pkg_event.h | 46 | ||||
-rw-r--r-- | include/util.h | 74 | ||||
-rw-r--r-- | menu-daemon.manifest | 13 | ||||
-rw-r--r-- | packaging/menu-daemon.service | 12 | ||||
-rw-r--r-- | packaging/menu-daemon.spec | 70 | ||||
-rw-r--r-- | src/hw_key.c | 428 | ||||
-rw-r--r-- | src/menu_daemon.c | 341 | ||||
-rw-r--r-- | src/pkg_event.c | 307 |
24 files changed, 1743 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100755 index 0000000..165ed89 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,54 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(menu-daemon C) + +SET(PREFIX "/usr") +SET(EXEC_PREFIX "${PREFIX}/bin") +SET(LIBDIR "${PREFIX}/lib") +SET(CONFDIR "/etc") +SET(VERSION 0.1.0) + +INCLUDE(FindPkgConfig) +pkg_check_modules(pkgs REQUIRED + ail + aul + capi-system-media-key + db-util + dlog + ecore + ecore-evas + ecore-x + ecore-input + ecore-file + eet + eina + elementary + evas + heynoti + syspopup-caller + utilX + vconf + x11 +) + + +ADD_DEFINITIONS("-DLOG_TAG=\"${PROJECT_NAME}\"") + +FOREACH (flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) +ADD_DEFINITIONS(${EXTRA_CFLAGS}) +ADD_EXECUTABLE(${PROJECT_NAME} + src/hw_key.c + src/pkg_event.c + src/menu_daemon.c +) +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/include) + +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${EXEC_PREFIX}) + +ADD_SUBDIRECTORY(data) + + + +# End of a file @@ -0,0 +1,75 @@ +Flora License + +Version 1.0, May, 2012 + +http://www.tizenopensource.org/license + +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. + +"Tizen Certified Platform" shall mean a software platform that complies with the standards set forth in the Compatibility Definition Document and passes the Compatibility Test Suite as defined from time to time by the Tizen Technical Steering Group and certified by the Tizen Association or its designated agent. + +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 solely as incorporated into a Tizen Certified Platform, 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 solely as incorporated into a Tizen Certified Platform 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 pursuant to the copyright license above, in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: + + 1. You must give any other recipients of the Work or Derivative Works a copy of this License; and + + 2. You must cause any modified files to carry prominent notices stating that You changed the files; and + + 3. 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 + + 4. 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 Flora License to your work + +To apply the Flora 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 Flora License, Version 1.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.tizenopensource.org/license + + 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/data/CMakeLists.txt b/data/CMakeLists.txt new file mode 100644 index 0000000..a649cde --- /dev/null +++ b/data/CMakeLists.txt @@ -0,0 +1,7 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) + +# Install +INSTALL(FILES menudaemon DESTINATION ${CONFDIR}/init.d) +INSTALL(FILES menudaemon.fast DESTINATION ${CONFDIR}/init.d) + +#End of a file diff --git a/data/menudaemon b/data/menudaemon new file mode 100755 index 0000000..22fc127 --- /dev/null +++ b/data/menudaemon @@ -0,0 +1,4 @@ +#!/bin/sh +echo -e "<2>[${_G}menu-daemon start${C_}]" > /dev/kmsg +/usr/bin/menu-daemon & +sleep 9 diff --git a/data/menudaemon.fast b/data/menudaemon.fast new file mode 100755 index 0000000..281034b --- /dev/null +++ b/data/menudaemon.fast @@ -0,0 +1,3 @@ +#!/bin/sh +echo -e "<2>[${_G}menu-daemon start${C_}]" > /dev/kmsg +/usr/bin/menu-daemon & diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..707fbc0 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,44 @@ +menu-daemon (0.2.45) unstable; urgency=low + + * Git: magnolia/apps/home/menu-daemon + * Tag: menu-daemon_0.2.45 + + * SMACK - manifest + + -- Jin Yoon <jinny.yoon@samsung.com> Sun, 04 Nov 2012 09:23:25 +0900 + +menu-daemon (0.2.44) unstable; urgency=low + + * Git: magnolia/apps/home/menu-daemon + * Tag: menu-daemon_0.2.44 + + * remove the unnecessary parser file. + + -- Jin Yoon <jinny.yoon@samsung.com> Tue, 18 Sep 2012 13:58:37 +0900 + +menu-daemon (0.2.43) unstable; urgency=low + + * Git: magnolia/apps/home/menu-daemon + * Tag: menu-daemon_0.2.43 + + * remove the event for IN_CREATE of pkg_event's inotify. + + -- Jin Yoon <jinny.yoon@samsung.com> Fri, 31 Aug 2012 19:13:35 +0900 + +menu-daemon (0.2.42) unstable; urgency=low + + * Git: magnolia/apps/home/menu-daemon + * Tag: menu-daemon_0.2.42 + + * don't launch home-screen when an app is dead. + + -- Jin Yoon <jinny.yoon@samsung.com> Fri, 24 Aug 2012 18:17:50 +0900 + +menu-daemon (0.2.41) unstable; urgency=low + + * Git: shared1/pkgs/m/menu-daemon + * Tag: menu-daemon_0.2.41 + + * [Modify] Copyright + + -- Jin Yoon <jinny.yoon@samsung.com> Wed, 22 Feb 2012 15:14:00 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100755 index 0000000..7725f48 --- /dev/null +++ b/debian/control @@ -0,0 +1,19 @@ +Source: menu-daemon +Section: utils +Priority: extra +Maintainer: Jin Yoon <jinny.yoon@samsung.com>, Youngjoo Park <yjoo93.park@samsung.com> +Build-Depends: debhelper (>= 5), libelm-dev, libslp-setting-dev, libefreet-dev, dlog-dev, libecore-dev, libaul-1-dev, syspopup-caller-dev, libheynoti-dev, libslp-utilx-dev, libail-0-dev, capi-system-media-key-dev +Homepage: N/A +Standards-Version: 0.1.0 + +Package: menu-daemon +Section: utils +Architecture: any +Depends: ${shlibs:Depends}, ${misc:Depends}, libelm, libslp-setting-0, libefreet, libdlog-0, libaul-1, syspopup-caller-0, libheynoti-0, libslp-utilx-0, libail-0, capi-system-media-key +Description: menu-daemon (Grab H/W key, Package manifest file parsing) + +Package: menu-daemon-dbg +Section: debug +Architecture: any +Depends: menu-daemon (= ${Source-Version}) +Description: menu-ademon (Grab H/W key, Package manifest file parsing) (unstripped) diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/copyright diff --git a/debian/jobs b/debian/jobs new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/debian/jobs diff --git a/debian/menu-daemon.install.in b/debian/menu-daemon.install.in new file mode 100644 index 0000000..bb3051a --- /dev/null +++ b/debian/menu-daemon.install.in @@ -0,0 +1,2 @@ +/etc/init.d/* +/usr/bin/* diff --git a/debian/menu-daemon.postinst b/debian/menu-daemon.postinst new file mode 100755 index 0000000..38c2969 --- /dev/null +++ b/debian/menu-daemon.postinst @@ -0,0 +1,13 @@ +#!/bin/sh + +vconf_init() +{ + vconftool set -t string memory/menuscreen/desktop "0" -i -f + vconftool set -t int memory/idle-screen/is_idle_screen_launched "0" -i -u 5000 -f +} + +vconf_init +ln -sf /etc/init.d/menudaemon /etc/rc.d/rc3.d/S46menudaemon +ln -sf /etc/init.d/menudaemon.fast /etc/rc.d/rc4.d/S85menudaemon + +# End of a file diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..74d350c --- /dev/null +++ b/debian/rules @@ -0,0 +1,133 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# This file was originally written by Joey Hess and Craig Small. +# As a special exception, when this file is copied by dh-make into a +# dh-make output file, you may use that output file without restriction. +# This special exception was added by Craig Small in version 0.37 of dh-make. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +CFLAGS += -Wall -Werror -fpie -Winline +CXXFLAGS += -Wall -Werror -fpie -Winline +LDFLAGS ?= +PREFIX ?= /usr +DATADIR ?= /opt + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 + CXXFLAGS += -O0 +else + CFLAGS += -O2 + CXXFLAGS += -O2 +endif + +ifneq (,$(findstring arm,$(DEB_HOST_ARCH))) + export ARCH = arm +else + export ARCH = i686 +endif + +LDFLAGS += -Wl,--rpath=$(PREFIX)/lib -Wl,--hash-style=both -Wl,--as-needed + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS)" CXXFLAGS="$(CXXFLAGS)" LDFLAGS="$(LDFLAGS)" cmake . -DCMAKE_INSTALL_PREFIX=$(PREFIX) + + touch configure-stamp + +build: build-stamp + +build-stamp: configure-stamp + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + #docbook-to-man debian/wavplayer.sgml > wavplayer.1 + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + cat $$f > $${f%.in}; \ + sed -i -e "s#@PREFIX@#$(PREFIX)#g" $${f%.in}; \ + sed -i -e "s#@DATADIR@#$(DATADIR)#g" $${f%.in}; \ + done + + + touch $@ + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) clean + rm -rf CMakeCache.txt + rm -rf CMakeFiles + rm -rf cmake_install.cmake + rm -rf Makefile + rm -rf install_manifest.txt + + rm -rf data/CMakeCache.txt + rm -rf data/CMakeFiles + rm -rf data/cmake_install.cmake + rm -rf data/install_manifest.txt + rm -rf data/Makefile + + rm -rf data/*.edj + + for f in `find $(CURDIR)/debian/ -name "*.in"`; do \ + rm -f $${f%.in}; \ + done + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/wavplayer. + $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot +# dh_installchangelogs +# dh_installdocs +# dh_installexamples + dh_install --sourcedir=debian/tmp +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_python +# dh_installinit +# dh_installcron +# dh_installinfo +# dh_installman + dh_link + dh_strip --dbg-package=menu-daemon-dbg + dh_compress + dh_fixperms +# dh_perl + dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/include/desktop_to_db.h b/include/desktop_to_db.h new file mode 100644 index 0000000..1494272 --- /dev/null +++ b/include/desktop_to_db.h @@ -0,0 +1,73 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 APP_INFO_DB_FILE "/opt/dbspace/.app_info.db" + +#define DESKTOP_FILE_PATH "/usr/share/install-info/application" +#define ORDER_FILE_PATH "/usr/share/install-info/.order/order" + +#define BUF_SIZE 40960 +#define APPS_PER_PAGE 19 + +typedef struct +{ + /* Origin field */ + char* package; + char* exec; + char* name; + char* type; + char* icon; + char* categories; + char* version; + char* mimetype; + int nodisplay; + + /* SLP field */ + char* x_slp_service; + char* x_slp_packagetype; + char* x_slp_packagecategories; + char* x_slp_uri; + int x_slp_taskmanage; + int x_slp_multiple; + int x_slp_removable; + int x_slp_baselayoutwidth; + int x_slp_baselayoutheight; + int x_slp_ishorizontalscale; + int x_slp_eventnotificationsetting; + + /* Invisible fields in the desktop file */ + char* desktop; + int activate; +} app_info_t; + + + +#if !defined(_MENU_COMPAT_H) +bool desktop_add(char* desktop, void* data); +bool desktop_update(char* desktop, void* data); +bool desktop_remove(char* desktop, void* data); +bool desktop_read(char *desktop, void *data); +void load_directory(const char *directory, int update_all); +char* desktop_to_pkgname(const char* desktop); +#endif + + + + + +// End of a file diff --git a/include/hw_key.h b/include/hw_key.h new file mode 100644 index 0000000..594e810 --- /dev/null +++ b/include/hw_key.h @@ -0,0 +1,24 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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. + */ + + + +extern void destroy_key_window(void); +extern void create_key_window(void); + + + +// End of a file diff --git a/include/pkg_event.h b/include/pkg_event.h new file mode 100644 index 0000000..0445093 --- /dev/null +++ b/include/pkg_event.h @@ -0,0 +1,46 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 __NOTIFIER_H__ +#define __NOTIFIER_H__ +#include <stdbool.h> + +#if !defined(PUBLIC) +#define PUBLIC __attribute__((visibility("default"))) /**<All other from outside modules can access this typed API */ +#endif + +#if !defined(PROTECTED) +#define PROTECTED __attribute__((visibility("hidden"))) /**<All other from outside modules can not access this directly */ +#endif + +#if !defined(PRIVATE) +#define PRIVATE __attribute__((visibility("internal"))) /**<Does not export APIs to the other. only can be accessed in this module */ +#endif + + +struct desktop_notifier { + int number; + int ifd; + Ecore_Fd_Handler *handler; +}; + + +PRIVATE void pkg_event_init(void); +PRIVATE void pkg_event_fini(void); + +#endif diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..eb52419 --- /dev/null +++ b/include/util.h @@ -0,0 +1,74 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 __MENU_DAEMON_UTIL_H__ +#define __MENU_DAEMON_UTIL_H__ +#include <dlog.h> + +#define HOME_SCREEN_PKG_NAME "org.tizen.menu-screen" +#define CONF_PATH_NUMBER 1024 + +/* Log */ +#if !defined(_W) +#define _W(fmt, arg...) LOGW("[%s:%d] "fmt"\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_D) +#define _D(fmt, arg...) LOGD("[%s:%d] "fmt"\n", __func__, __LINE__, ##arg) +#endif + +#if !defined(_E) +#define _E(fmt, arg...) LOGE("[%s:%d] "fmt"\n", __func__, __LINE__, ##arg) +#endif + +#define retv_if(expr, val) do { \ + if(expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return (val); \ + } \ +} while (0) + +#define ret_if(expr) do { \ + if(expr) { \ + _E("(%s) -> %s() return", #expr, __FUNCTION__); \ + return; \ + } \ +} while (0) + +#define goto_if(expr, val) do { \ + if(expr) { \ + _E("(%s) -> goto", #expr); \ + goto val; \ + } \ +} while (0) + +#define break_if(expr) { \ + if(expr) { \ + _E("(%s) -> break", #expr); \ + break; \ + } \ +} + +#define continue_if(expr) { \ + if(expr) { \ + _E("(%s) -> continue", #expr); \ + continue; \ + } \ +} + +#endif /* __MENU_DAEMON_UTIL_H__ */ diff --git a/menu-daemon.manifest b/menu-daemon.manifest new file mode 100644 index 0000000..a1802a6 --- /dev/null +++ b/menu-daemon.manifest @@ -0,0 +1,13 @@ +<manifest> + <define> + <domain name="menu-daemon" /> + </define> + <request> + <domain name="menu-daemon" /> + </request> + <assign> + <filesystem path="/usr/bin/menu-daemon" label="menu-daemon" exec_label="menu-daemon" /> + <filesystem path="/etc/init.d/menudaemon" label="_" exec_label="_" /> + <filesystem path="/etc/init.d/menudaemon.fast" label="_" exec_label="_"/> + </assign> +</manifest> diff --git a/packaging/menu-daemon.service b/packaging/menu-daemon.service new file mode 100644 index 0000000..5b54ab9 --- /dev/null +++ b/packaging/menu-daemon.service @@ -0,0 +1,12 @@ + +[Unit] +Description=Start the menu-daemon service +Before=core-efl.target +After=xorg.target + +[Service] +ExecStart=/usr/bin/menu-daemon + +[Install] +WantedBy=tizen-mobile-session.target + diff --git a/packaging/menu-daemon.spec b/packaging/menu-daemon.spec new file mode 100644 index 0000000..b56e0e3 --- /dev/null +++ b/packaging/menu-daemon.spec @@ -0,0 +1,70 @@ +%define _optdir /opt +%define _appdir %{_optdir}/apps +%define _opt_datadir %{_optdir}/share + +Name: menu-daemon +Summary: Menu daemon +Version: 0.2.45 +Release: 1 +Group: framework +License: Flora Software License +Source0: menu-daemon-%{version}.tar.gz +Source101: menu-daemon.service +BuildRequires: pkgconfig(ail) +BuildRequires: pkgconfig(aul) +BuildRequires: pkgconfig(capi-system-media-key) +BuildRequires: pkgconfig(db-util) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(ecore) +BuildRequires: pkgconfig(eet) +BuildRequires: pkgconfig(eina) +BuildRequires: pkgconfig(elementary) +BuildRequires: pkgconfig(evas) +BuildRequires: pkgconfig(heynoti) +BuildRequires: pkgconfig(syspopup-caller) +BuildRequires: pkgconfig(utilX) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(x11) +BuildRequires: cmake +BuildRequires: edje-bin +BuildRequires: embryo-bin +BuildRequires: eet-bin +BuildRequires: gettext-tools + +Requires(post): /usr/bin/vconftool + +%description +menu-daemon (Grab H/W key, Package manifest file parsing) + +%prep +%setup -q + +%build +export LDFLAGS+="-Wl,--hash-style=both -Wl,--as-needed" +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} +make %{?jobs:-j%jobs} + +%install +%make_install +mkdir -p %{buildroot}/%{_sysconfdir}/rc.d/rc3.d +mkdir -p %{buildroot}/%{_sysconfdir}/rc.d/rc4.d +ln -sf ../init.d/menudaemon %{buildroot}/%{_sysconfdir}/rc.d/rc3.d/S46menudaemon +ln -sf ../init.d/menudaemon.fast %{buildroot}/%{_sysconfdir}/rc.d/rc4.d/S85menudaemon + +mkdir -p %{buildroot}%{_libdir}/systemd/user/core-efl.target.wants +install -m 0644 %SOURCE101 %{buildroot}%{_libdir}/systemd/user/ +ln -s ../menu-daemon.service %{buildroot}%{_libdir}/systemd/user/core-efl.target.wants/menu-daemon.service + +%post +vconftool set -t string memory/menuscreen/desktop "0" -i -f +vconftool set -t int memory/idle-screen/is_idle_screen_launched "0" -i -u 5000 -f + +%files +%manifest %{name}.manifest +%attr(0755,-,-) %{_sysconfdir}/init.d/menudaemon +%attr(0755,-,-) %{_sysconfdir}/init.d/menudaemon.fast +%attr(0755,root,root) %{_sysconfdir}/rc.d/rc3.d/S46menudaemon +%attr(0755,root,root) %{_sysconfdir}/rc.d/rc4.d/S85menudaemon +%{_bindir}/menu-daemon +%{_libdir}/systemd/user/menu-daemon.service +%{_libdir}/systemd/user/core-efl.target.wants/menu-daemon.service diff --git a/src/hw_key.c b/src/hw_key.c new file mode 100644 index 0000000..deccb9b --- /dev/null +++ b/src/hw_key.c @@ -0,0 +1,428 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 <ail.h> +#include <bundle.h> +#include <Elementary.h> +#include <Ecore_X.h> +#include <Ecore_Input.h> +#include <syspopup_caller.h> +#include <utilX.h> +#include <vconf.h> +#include <system/media_key.h> + +#include "hw_key.h" +#include "util.h" + +#define TASKMGR_PKG_NAME "org.tizen.taskmgr" +#define CAMERA_PKG_NAME "org.tizen.camera-app" +#define CALLLOG_PKG_NAME "org.tizen.calllog" +#define SEARCH_PKG_NAME "org.tizen.smartsearch" +#define MUSIC_PLAYER_PKG_NAME "org.tizen.music-player" + + + +static struct { + Ecore_X_Window win; + Ecore_Event_Handler *key_up; + Ecore_Event_Handler *key_down; + Ecore_Timer *long_press; + Ecore_Timer *single_timer; + Ecore_Timer *volume_up_long_press; + Ecore_Timer *volume_down_long_press; + Eina_Bool cancel; +} key_info = { + .win = 0x0, + .key_up = NULL, + .key_down = NULL, + .long_press = NULL, + .single_timer = NULL, + .volume_up_long_press = NULL, + .volume_down_long_press = NULL, + .cancel = EINA_FALSE, +}; + + + +static Eina_Bool _launch_taskmgr_cb(void* data) +{ + _D("Launch TASKMGR"); + + key_info.long_press = NULL; + + if (aul_open_app(TASKMGR_PKG_NAME) < 0) + _E("Failed to launch the taskmgr"); + + return ECORE_CALLBACK_CANCEL; +} + + + +static Eina_Bool _launch_home_screen(void *data) +{ + char *package; + + syspopup_destroy_all(); + key_info.single_timer = NULL; + + package = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME); + if (package) { + int ret; + + ret = aul_open_app(package); + if (ret < 0) { + if (!strcmp(package, HOME_SCREEN_PKG_NAME)) { + _E("Default homescreen is not able to launch"); + } else { + _E("Package %s is not exists, rollback to default home", package); + if (0 != vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME)) { + _E("Cannot set value(%s) into key(%s)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME); + } + ret = aul_open_app(HOME_SCREEN_PKG_NAME); + if (ret < 0) + _E("Failed to launch default home"); + } + } + + free(package); + } else { + if (0 != vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME)) { + _E("Cannot set value(%s) into key(%s)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME); + } + + if (aul_open_app(HOME_SCREEN_PKG_NAME) < 0) + _E("Cannot open default home"); + } + + return ECORE_CALLBACK_CANCEL; +} + + + +inline static void _launch_search(void) +{ + _D("Launch smartsearch"); + if (aul_open_app(SEARCH_PKG_NAME) < 0) + _E("Cannot open Smart-search"); + + return; +} + + + +inline static int _release_home_key(void) +{ + retv_if(NULL == key_info.long_press, EXIT_SUCCESS); + ecore_timer_del(key_info.long_press); + key_info.long_press = NULL; + + if (NULL == key_info.single_timer) { + key_info.single_timer = ecore_timer_add(0.3, _launch_home_screen, NULL); + return EXIT_SUCCESS; + } + ecore_timer_del(key_info.single_timer); + key_info.single_timer = NULL; + + syspopup_destroy_all(); + _launch_search(); + + return EXIT_SUCCESS; +} + + + +inline static void _release_multimedia_key(const char *value) +{ + bundle *b; + int ret; + + _D("Multimedia key is released with %s", value); + ret_if(NULL == value); + + b = bundle_create(); + if (!b) { + _E("Cannot create bundle"); + return; + } + + bundle_add(b, "multimedia_key", value); + ret = aul_launch_app(MUSIC_PLAYER_PKG_NAME, b); + bundle_free(b); + + if (ret < 0) + _E("Failed to launch the running apps, ret : %d", ret); +} + + + +static Eina_Bool _key_release_cb(void *data, int type, void *event) +{ + Evas_Event_Key_Up *ev = event; + + _D("Released"); + + if (!ev) { + _D("Invalid event object"); + return ECORE_CALLBACK_RENEW; + } + + if (!strcmp(ev->keyname, KEY_END)) { + } else if (!strcmp(ev->keyname, KEY_CAMERA)) { + } else if (!strcmp(ev->keyname, KEY_SEND)) { + } else if (!strcmp(ev->keyname, KEY_SELECT)) { + if (EINA_TRUE == key_info.cancel) { + _D("Cancel key is activated"); + if (key_info.long_press) { + ecore_timer_del(key_info.long_press); + key_info.long_press = NULL; + } + + if (key_info.single_timer) { + ecore_timer_del(key_info.single_timer); + key_info.single_timer = NULL; + } + + return ECORE_CALLBACK_RENEW; + } + + _release_home_key(); + } else if (!strcmp(ev->keyname, KEY_PAUSE)) { + } else if (!strcmp(ev->keyname, KEY_VOLUMEDOWN)) { + if (key_info.volume_down_long_press) { + ecore_timer_del(key_info.volume_down_long_press); + key_info.volume_down_long_press = NULL; + } + + if (EINA_TRUE == key_info.cancel) { + _D("Cancel key is activated"); + return ECORE_CALLBACK_RENEW; + } + if (syspopup_launch("volume", NULL) < 0) + _D("Failed to launch the volume popup"); + } else if (!strcmp(ev->keyname, KEY_VOLUMEUP)) { + if (key_info.volume_up_long_press) { + ecore_timer_del(key_info.volume_up_long_press); + key_info.volume_up_long_press = NULL; + } + if (syspopup_launch("volume", NULL) < 0) + _D("Failed to launch the volume popup"); + } else if (!strcmp(ev->keyname, KEY_CANCEL)) { + _D("CANCEL Key is released"); + key_info.cancel = EINA_FALSE; + } else if (!strcmp(ev->keyname, KEY_PAUSECD)) { + _release_multimedia_key("KEY_PAUSECD"); + } else if (!strcmp(ev->keyname, KEY_PLAYCD)) { + _release_multimedia_key("KEY_PLAYCD"); + } else if (!strcmp(ev->keyname, KEY_MEDIA)) { + _release_multimedia_key("KEY_PLAYCD"); + } + + return ECORE_CALLBACK_RENEW; +} + + + +static Eina_Bool _volume_up_cb(void* data) +{ + bundle *b; + + _D("Long press : Volume up"); + key_info.volume_up_long_press = NULL; + + b = bundle_create(); + if (!b) { + _E("Cannot create bundle"); + return ECORE_CALLBACK_CANCEL; + } + + bundle_add(b, "LONG_PRESS", "VOLUME_UP"); + if (syspopup_launch("volume", b) < 0) + _D("Failed to launch the volume popup"); + bundle_free(b); + + return ECORE_CALLBACK_CANCEL; +} + + + +static Eina_Bool _volume_down_cb(void* data) +{ + bundle *b; + + _D("Long press : Volume down"); + key_info.volume_down_long_press = NULL; + + if (EINA_TRUE == key_info.cancel) + return ECORE_CALLBACK_CANCEL; + + b = bundle_create(); + if (!b) { + _E("Cannot create bundle"); + return ECORE_CALLBACK_CANCEL; + } + + bundle_add(b, "LONG_PRESS", "VOLUME_DOWN"); + if (syspopup_launch("volume", b) < 0) + _D("Failed to launch the volume popup"); + bundle_free(b); + + return ECORE_CALLBACK_CANCEL; +} + + + +static Eina_Bool _key_press_cb(void *data, int type, void *event) +{ + Evas_Event_Key_Down *ev = event; + + _D("Pressed"); + + if (!ev) { + _D("Invalid event object"); + return ECORE_CALLBACK_RENEW; + } + + if (!strcmp(ev->keyname, KEY_SEND)) { + _D("Launch calllog"); + if (aul_open_app(CALLLOG_PKG_NAME) < 0) + _E("Failed to launch %s", CALLLOG_PKG_NAME); + } else if(!strcmp(ev->keyname, KEY_CAMERA)) { + _D("Launch camera"); + if (aul_open_app(CAMERA_PKG_NAME) < 0) + _E("Failed to launch %s", CAMERA_PKG_NAME); + } else if (!strcmp(ev->keyname, KEY_VOLUMEDOWN)) { + key_info.cancel = EINA_FALSE; + if (key_info.volume_down_long_press) { + ecore_timer_del(key_info.volume_down_long_press); + key_info.volume_down_long_press = NULL; + } + key_info.volume_down_long_press = ecore_timer_add(0.5, _volume_down_cb, NULL); + if (NULL == key_info.volume_down_long_press) + _E("Cannot add timer for volume_down_cb"); + } else if (!strcmp(ev->keyname, KEY_VOLUMEUP)) { + if (key_info.volume_up_long_press) { + ecore_timer_del(key_info.volume_up_long_press); + key_info.volume_up_long_press = NULL; + } + key_info.volume_up_long_press = ecore_timer_add(0.5, _volume_up_cb, NULL); + if (NULL == key_info.volume_up_long_press) + _E("Cannot add timer for volume_up_cb"); + } else if (!strcmp(ev->keyname, KEY_SELECT)) { + if (key_info.long_press) { + ecore_timer_del(key_info.long_press); + key_info.long_press = NULL; + } + + key_info.long_press = ecore_timer_add(0.5, _launch_taskmgr_cb, NULL); + if (!key_info.long_press) + _E("Failed to add timer for long press detection"); + } else if (!strcmp(ev->keyname, KEY_CANCEL)) { + _D("Cancel button is pressed"); + if (key_info.volume_down_long_press) { + ecore_timer_del(key_info.volume_down_long_press); + key_info.volume_down_long_press = NULL; + } + key_info.cancel = EINA_TRUE; + _D("Cancel button is pressed"); + } else if (!strcmp(ev->keyname, KEY_PAUSECD) || !strcmp(ev->keyname, KEY_PLAYCD)) { + _D("Multimedia key is pressed"); + } else if (!strcmp(ev->keyname, KEY_MEDIA)) { + _D("Media key is pressed"); + } + + return ECORE_CALLBACK_RENEW; +} + + + +void _media_key_event_cb(media_key_e key, media_key_event_e status, void *user_data) +{ + _D("MEDIA KEY EVENT"); + if (MEDIA_KEY_STATUS_PRESSED == status) return; + + if (MEDIA_KEY_PAUSE == key) { + _release_multimedia_key("KEY_PAUSECD"); + } else if (MEDIA_KEY_PLAY == key) { + _release_multimedia_key("KEY_PLAYCD"); + } +} + + + +void create_key_window(void) +{ + key_info.win = ecore_x_window_input_new(0, 0, 0, 1, 1); + if (!key_info.win) { + _D("Failed to create hidden window"); + return; + } + + ecore_x_icccm_title_set(key_info.win, "menudaemon,key,receiver"); + ecore_x_netwm_name_set(key_info.win, "menudaemon,key,receiver"); + ecore_x_netwm_pid_set(key_info.win, getpid()); + + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_SELECT, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_CAMERA, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PAUSECD, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_PLAYCD, SHARED_GRAB); + utilx_grab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA, SHARED_GRAB); + + key_info.key_up = ecore_event_handler_add(ECORE_EVENT_KEY_UP, _key_release_cb, NULL); + if (!key_info.key_up) + _D("Failed to register a key up event handler"); + + key_info.key_down = ecore_event_handler_add(ECORE_EVENT_KEY_DOWN, _key_press_cb, NULL); + if (!key_info.key_down) + _D("Failed to register a key down event handler"); + + media_key_reserve(_media_key_event_cb, NULL); +} + + + +void destroy_key_window(void) +{ + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_SELECT); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEDOWN); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_VOLUMEUP); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_CAMERA); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_PAUSECD); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_PLAYCD); + utilx_ungrab_key(ecore_x_display_get(), key_info.win, KEY_MEDIA); + + if (key_info.key_up) { + ecore_event_handler_del(key_info.key_up); + key_info.key_up = NULL; + } + + if (key_info.key_down) { + ecore_event_handler_del(key_info.key_down); + key_info.key_down = NULL; + } + + ecore_x_window_delete_request_send(key_info.win); + key_info.win = 0x0; + + media_key_release(); +} + + + +// End of a file diff --git a/src/menu_daemon.c b/src/menu_daemon.c new file mode 100644 index 0000000..71b81d1 --- /dev/null +++ b/src/menu_daemon.c @@ -0,0 +1,341 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 <ail.h> +#include <aul.h> +#include <db-util.h> +#include <Elementary.h> +#include <fcntl.h> +#include <heynoti.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <vconf.h> +#include <errno.h> + +#include "desktop_to_db.h" +#include "hw_key.h" +#include "pkg_event.h" +#include "util.h" + + +int errno; + + +#define QUERY_UPDATE_NAME "UPDATE app_info SET name='%s' where package='%s';" +#define SAT_DESKTOP_FILE "/opt/share/applications/org.tizen.sat-ui.desktop" +#define HIBERNATION_DIR "/tmp/hibernation" +#define HIBERNATION_READY "/tmp/hibernation/menuscreen_ready" + + + +// Define prototype of the "hidden API of AUL" +extern int aul_listen_app_dead_signal(int (*func)(int signal, void *data), void *data); + + + +static struct info { + pid_t pid; + int power_off; +} s_info = { + .pid = -1, + .power_off = 0, +}; + + + +static inline char *_get_selected_pkgname(void) +{ + char *pkgname; + + pkgname = vconf_get_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME); + if (!pkgname) { + _E("Cannot get pkgname from vconf."); + + if (0 != vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME)) { + _E("Cannot set value(%s) into key(%s)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME); + } + + pkgname = strdup(HOME_SCREEN_PKG_NAME); + if (!pkgname) { + _E("strdup error for pkgname, %s", strerror(errno)); + return NULL; + } + } + + return pkgname; +} + + + +static inline void _open_homescreen(const char *pkgname) +{ + int ret; + char *homescreen = (char *) pkgname; + + ret = aul_open_app(homescreen); + _D("can%s launch %s now. (%d)", ret < 0 ? "not" : "", homescreen, ret); + if (ret < 0 && strcmp(homescreen, HOME_SCREEN_PKG_NAME)) { + if (0 != vconf_set_str(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME)) { + _E("Cannot set value(%s) into key(%s)", VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, HOME_SCREEN_PKG_NAME); + } + + ret = aul_open_app(HOME_SCREEN_PKG_NAME); + if (ret < 0) { + _E("Failed to open a default home, %s", HOME_SCREEN_PKG_NAME); + } else { + homescreen = HOME_SCREEN_PKG_NAME; + } + } + + s_info.pid = ret; +} + + + +static void _show_cb(keynode_t* node, void *data) +{ + int seq; + char *pkgname; + + _D("[MENU_DAEMON] _show_cb is invoked"); + + pkgname = _get_selected_pkgname(); + if (!pkgname) + return; + + if (node) { + seq = vconf_keynode_get_int(node); + } else { + if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) { + _E("Failed to get sequence info"); + free(pkgname); + return; + } + } + + switch (seq) { + case 0: + if (s_info.pid > 0) { + int pid; + _D("pid[%d] is terminated.", s_info.pid); + + pid = s_info.pid; + s_info.pid = -1; /* to freeze the dead_cb */ + + if (aul_terminate_pid(pid) != AUL_R_OK) + _E("Failed to terminate %d", s_info.pid); + } + break; + case 1: + _open_homescreen(pkgname); + break; + default: + _E("False sequence [%d]", seq); + break; + } + + free(pkgname); + return; + +} + + + +static void _pkg_changed(keynode_t* node, void *data) +{ + char *pkgname; + int seq; + + if (vconf_get_int(VCONFKEY_STARTER_SEQUENCE, &seq) < 0) { + _E("Do nothing, there is no sequence info yet"); + return; + } + + if (seq < 1) { + _E("Sequence is not ready yet, do nothing"); + return; + } + + _D("_pkg_changed is invoked"); + + pkgname = _get_selected_pkgname(); + if (!pkgname) + return; + + _D("pkg_name : %s", pkgname); + + if (s_info.pid > 0) { + char old_pkgname[256]; + + if (aul_app_get_pkgname_bypid(s_info.pid, old_pkgname, sizeof(old_pkgname)) == AUL_R_OK) { + if (!strcmp(pkgname, old_pkgname)) { + _D("Package is changed but same package is selected"); + free(pkgname); + return; + } + } + + if (aul_terminate_pid(s_info.pid) != AUL_R_OK) + _D("Failed to terminate pid %d", s_info.pid); + } else { + /* If there is no running home */ + _open_homescreen(pkgname); + } + + /* NOTE: Dead callback will catch the termination of a current menuscreen + * _open_homescreen(pkgname); + */ + free(pkgname); + return; +} + + + +static int _dead_cb(int pid, void *data) +{ + char *pkgname; + + if (s_info.power_off) { + _D("Power off. ignore dead cb\n"); + return 0; + } + + _D("Process %d is termianted", pid); + + if (pid < 0) + return 0; + + if (pid != s_info.pid || s_info.pid <= 0) { + _D("Unknown process, ignore it (pid %d, menu pid %d)", pid, s_info.pid); + return 0; + } + + pkgname = _get_selected_pkgname(); + if (!pkgname) + return 0; + + _D("pkg_name : %s", pkgname); + + /* Relaunch */ + _open_homescreen(pkgname); + free(pkgname); + return 0; +} + + + +static void _hibernation_preleave_cb(void *data) +{ + _D( "[MENU_DAEMON]_hibernation_preleave_cb is invoked"); + + aul_launch_init(NULL,NULL); + aul_listen_app_dead_signal(_dead_cb, NULL); + + create_key_window(); + pkg_event_init(); + + if (unlink(SAT_DESKTOP_FILE) != 0) + _E("cannot remove sat-ui desktop."); + + if (vconf_notify_key_changed(VCONFKEY_SETAPPL_SELECTED_PACKAGE_NAME, _pkg_changed, NULL) < 0) + _E("Failed to add callback for package change event"); + + if (vconf_notify_key_changed(VCONFKEY_STARTER_SEQUENCE, _show_cb, NULL) < 0) + _E("Failed to add callback for show event"); + + _pkg_changed(NULL, NULL); + // THIS ROUTINE IS FOR SAT. + vconf_set_int(VCONFKEY_IDLE_SCREEN_LAUNCHED, VCONFKEY_IDLE_SCREEN_LAUNCHED_TRUE); +} + + + +static void power_off_cb(void *data) +{ + _D("heynoti power off\n"); + s_info.power_off = 1; +} + + + +int elm_main(int argc, char *argv[]) +{ + FILE *fp; + int fd; + int ret; + + elm_init(argc, argv); + + fd = heynoti_init(); + if (fd < 0) + fprintf(stderr, "heynoti_init\n"); + + ret = heynoti_subscribe(fd, "power_off_start", power_off_cb, NULL); + if (ret < 0) + fprintf(stderr, "heynoti_subscribe\n"); + + fp = fopen("/opt/etc/.hib_capturing", "r"); + if (!fp) { + fprintf(stderr, "[MENU_DAEMON]hib_capturing file is not found\n"); + _hibernation_preleave_cb(NULL); + } else { + fprintf(stderr,"\n\n\n Menu Daemon enter %s hey noti init\n", __func__); + if (fd < 0) { + fprintf(stderr, "[MENU_DAEMON]\n\n\n Hey Noti Init Failed\n"); + } else { + if (heynoti_subscribe(fd, "HIBERNATION_PRELEAVE", _hibernation_preleave_cb, NULL)) { + fprintf(stderr,"Heynoti subscribe is failed\n"); + } else { + fprintf(stderr,"Heynoti subscribe is done\n"); + int fd; + if (mkdir(HIBERNATION_DIR, 0777) != -1) + _D("Make a directory - [%s]", HIBERNATION_DIR); + + fd = creat(HIBERNATION_READY, 0644); + if (fd != -1) { + _D("Create a file for hibernation_ready"); + close(fd); + } + } + + } + fclose(fp); + } + + if (heynoti_attach_handler(fd)) + fprintf(stderr,"Heynoti attach handler is failed\n"); + else + fprintf(stderr,"Heynoti attach handler is done\n"); + + elm_run(); + + pkg_event_fini(); + destroy_key_window(); + + elm_exit(); + return 0; +} + + + +ELM_MAIN() + + + +// End of a file diff --git a/src/pkg_event.c b/src/pkg_event.c new file mode 100644 index 0000000..dcc5781 --- /dev/null +++ b/src/pkg_event.c @@ -0,0 +1,307 @@ + /* + * Copyright 2012 Samsung Electronics Co., Ltd + * + * Licensed under the Flora License, Version 1.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.tizenopensource.org/license + * + * 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 <ail.h> +#include <errno.h> +#include <Elementary.h> +#include <Ecore.h> +#include <Ecore_File.h> +#include <stdio.h> +#include <sys/inotify.h> +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <stdbool.h> +#include <unistd.h> +#include <vconf.h> + +#include "desktop_to_db.h" +#include "pkg_event.h" +#include "util.h" + + +#define CONF_FILE "/usr/share/install-info/desktop.conf" +#define BUFSZE 1024 + + +extern int errno; +struct inotify_path +{ + int wd; + char *path; +}; + +struct desktop_notifier s_desktop_notifier = { + .number = 0, + .ifd = 0, + .handler = NULL, +}; + + + +struct inotify_path paths[CONF_PATH_NUMBER]; + + +static Eina_Bool +directory_notify(void* data, Ecore_Fd_Handler* fd_handler) +{ + char *buf; + ssize_t read_size, len, i = 0; + int fd; + + fd = ecore_main_fd_handler_fd_get(fd_handler); + _D("There are some modification, ifd [%d]", fd); + + if (ioctl(fd, FIONREAD, &read_size) < 0) { + _E("Failed to get q size"); + return ECORE_CALLBACK_CANCEL; + } + + if (read_size <= 0) { + _E("Buffer is not ready!!!"); + return ECORE_CALLBACK_RENEW; + } + + buf = malloc(read_size); + if (!buf) { + _E("Failed to allocate heap for event handling"); + return ECORE_CALLBACK_RENEW; + } + + len = read(fd, buf, read_size); + if (len < 0) { + free(buf); + // Stop monitoring about this invalid file descriptor + return ECORE_CALLBACK_CANCEL; + } + + while (i < len) { + struct inotify_event* event = (struct inotify_event*) &buf[i]; + char *str_potksed = "potksed."; + char *package = NULL; + ssize_t idx; + int nev_name; + + // 1. check the extension of a file + nev_name = strlen(event->name) - 1; + for (idx = 0; nev_name >= 0 && str_potksed[idx]; idx++) { + if (event->name[nev_name] != str_potksed[idx]) { + break; + } + nev_name --; + } + + if (str_potksed[idx] != '\0' || nev_name < 0) { + _D("This is not a desktop file : %s", event->name); + i += sizeof(struct inotify_event) + event->len; + continue; + } + + package = strdup(event->name); + break_if(NULL == package); + + package[nev_name + 1] = '\0'; + _D("Package : %s", package); + + // add & update + if (event->mask & IN_CLOSE_WRITE || event->mask & IN_MOVED_TO) { // for moving + ail_appinfo_h ai = NULL; + ail_error_e ret; + + ret = ail_package_get_appinfo(package, &ai); + if (ai) ail_package_destroy_appinfo(ai); + + + if (AIL_ERROR_NO_DATA == ret) { + if (ail_desktop_add(package) < 0) { + _D("Failed to add a new package (%s)", event->name); + } + } else if (AIL_ERROR_OK == ret) { + if (ail_desktop_update(package) < 0) { + _D("Failed to add a new package (%s)", event->name); + } + } else + ; + // delete + } else if (event->mask & IN_DELETE) { // for deleting + if (ail_desktop_remove(package) < 0) + _D("Failed to remove a package (%s)", event->name); + } else { + _D("this event is not dealt with inotify"); + } + + free(package); + + i += sizeof(struct inotify_event) + event->len; + } + + free(buf); + return ECORE_CALLBACK_RENEW; +} + + + +static inline char *_ltrim(char *str) +{ + retv_if(NULL == str, NULL); + while (*str && (*str == ' ' || *str == '\t' || *str == '\n')) str ++; + return str; +} + + + +static inline int _rtrim(char *str) +{ + int len; + + retv_if(NULL == str, 0); + + len = strlen(str); + while (--len >= 0 && (str[len] == ' ' || str[len] == '\n' || str[len] == '\t')) { + str[len] = '\0'; + } + + return len; +} + + + +static int _retrieve_conf_path(struct inotify_path* paths) +{ + char *line = NULL; + FILE *fp; + size_t size = 0; + ssize_t read; + int i = 0; + + fp = fopen(CONF_FILE, "r"); + if (NULL == fp) { + _E(CONF_FILE); + return -1; + } + + while ((read = getline(&line, &size, fp)) != -1 && i < CONF_PATH_NUMBER - 1) { + char *begin; + + if (size <= 0) break; + + begin = _ltrim(line); + _rtrim(line); + + if (*begin == '#' || *begin == '\0') continue; + + paths[i].path = strdup(begin); + i++; + } + + if (line) free(line); + paths[i].path = NULL; + fclose(fp); + + return i; +} + + + +static void _unretrieve_conf_path(struct inotify_path* paths, int number) +{ + register int i; + + for (i = 0; i < number; i ++) { + if (paths[i].path) { + free(paths[i].path); + paths[i].path = NULL; + } + } +} + + + +void pkg_event_init() +{ + int wd = 0; + int i; + + s_desktop_notifier.ifd = inotify_init(); + if (s_desktop_notifier.ifd == -1) { + _E("inotify_init error: %s", strerror(errno)); + return; + } + + s_desktop_notifier.number = _retrieve_conf_path(paths); + + for (i = 0; i < CONF_PATH_NUMBER && paths[i].path; i++) + { + _D("Configuration file for desktop file monitoring [%s] is added", paths[i].path); + if (access(paths[i].path, R_OK) != 0) + { + ecore_file_mkpath(paths[i].path); + if (chmod(paths[i].path, 0777) == -1) { + _E("cannot chmod %s", paths[i].path); + } + } + + wd = inotify_add_watch(s_desktop_notifier.ifd, paths[i].path, IN_CLOSE_WRITE | IN_MOVED_TO | IN_DELETE); + if (wd == -1) { + _E("inotify_add_watch error: %s", strerror(errno)); + close(s_desktop_notifier.ifd); + return; + } + + paths[i].wd = wd; + } + + s_desktop_notifier.handler = ecore_main_fd_handler_add(s_desktop_notifier.ifd, ECORE_FD_READ, directory_notify, NULL, NULL, NULL); + if (!s_desktop_notifier.handler) { + // TODO: Handles me.. EXCEPTION!! + _E("cannot add handler for inotify"); + } +} + + + +void pkg_event_fini(void) +{ + register int i; + + if (s_desktop_notifier.handler) { + ecore_main_fd_handler_del(s_desktop_notifier.handler); + } + + for (i = 0; i < CONF_PATH_NUMBER; i ++) { + if (paths[i].wd) { + if (inotify_rm_watch(s_desktop_notifier.ifd, paths[i].wd) < 0) { + char log[BUFSZE] = {0,}; + int ret; + + ret = strerror_r(errno, log, sizeof(log)); + _E("Error: %s", ret == 0? log : "unknown error"); + } + paths[i].wd = 0; + } + } + + _unretrieve_conf_path(paths, s_desktop_notifier.number); + + if (s_desktop_notifier.ifd) { + close(s_desktop_notifier.ifd); + s_desktop_notifier.ifd = 0; + } +} + + +// End of a file |