aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsrimaldia <hariasti.srimaldia-1@jp.alps.com>2016-12-09 20:05:35 +0900
committersrimaldia <hariasti.srimaldia-1@jp.alps.com>2016-12-09 20:05:35 +0900
commit18e149d5c2f7155ef2933fe4e3ac15837c99235d (patch)
tree9c6e16ce5663e624d896d14d9c76cd44d70aeffb
parent8751c24a726afeb0d65e9aeb031fe7c9240cb5b4 (diff)
add standalone wifi app
Signed-off-by: srimaldia <hariasti.srimaldia-1@jp.alps.com>
-rwxr-xr-xAUTHORS.txt2
-rwxr-xr-xCMakeLists.txt68
-rwxr-xr-xLICENSE-2.0.txt201
-rwxr-xr-xREADME.txt34
-rwxr-xr-xagent.c262
-rwxr-xr-xconfig.xml.in9
-rwxr-xr-xdoc/AppGrid.qml43
-rwxr-xr-xdoc/AppIcon.qml51
-rwxr-xr-xdoc/BottomBar.qml65
-rwxr-xr-xdoc/GridItem.qml45
-rwxr-xr-xdoc/Key.qml85
-rwxr-xr-xdoc/Keyboard.qml137
-rwxr-xr-xdoc/Main.qml101
-rwxr-xr-xdoc/README.md23
-rwxr-xr-xdoc/Rotated.qml17
-rwxr-xr-xdoc/Scaled.qml17
-rwxr-xr-xdoc/Scaled_04.qml17
-rwxr-xr-xdoc/Scaled_720p.qml17
-rwxr-xr-xdoc/TopBar.qml146
-rwxr-xr-xdoc/VolumeControl.qml97
-rwxr-xr-xdoc/images/AGL-Logo.pngbin0 -> 20091 bytes
-rwxr-xr-xdoc/images/AppHex.pngbin0 -> 9827 bytes
-rwxr-xr-xdoc/images/Hex-Background.jpgbin0 -> 119534 bytes
-rwxr-xr-xdoc/images/JLR-Logo.pngbin0 -> 35509 bytes
-rwxr-xr-xdoc/images/agl_icon.pngbin0 -> 25190 bytes
-rwxr-xr-xdoc/images/application_grid.pngbin0 -> 5427 bytes
-rwxr-xr-xdoc/images/backspace_icon.pngbin0 -> 640 bytes
-rwxr-xr-xdoc/images/blank_hexagon.pngbin0 -> 5405 bytes
-rwxr-xr-xdoc/images/browser_app_icon.pngbin0 -> 5474 bytes
-rwxr-xr-xdoc/images/browser_app_icon.svg100
-rwxr-xr-xdoc/images/bt_close.pngbin0 -> 1215 bytes
-rwxr-xr-xdoc/images/cameras_app_icon.pngbin0 -> 4408 bytes
-rwxr-xr-xdoc/images/cameras_app_icon.svg82
-rwxr-xr-xdoc/images/dashboard_app_icon.pngbin0 -> 5530 bytes
-rwxr-xr-xdoc/images/dashboard_app_icon.svg130
-rwxr-xr-xdoc/images/fingerprint_app_icon.pngbin0 -> 5919 bytes
-rwxr-xr-xdoc/images/fmradio_app_icon.pngbin0 -> 3732 bytes
-rwxr-xr-xdoc/images/fmradio_app_icon.svg110
-rwxr-xr-xdoc/images/googlemaps_app_icon.pngbin0 -> 3508 bytes
-rwxr-xr-xdoc/images/googlemaps_app_icon.svg86
-rwxr-xr-xdoc/images/homescreen_icon.pngbin0 -> 4606 bytes
-rwxr-xr-xdoc/images/hvac_app_icon.pngbin0 -> 4236 bytes
-rwxr-xr-xdoc/images/hvac_app_icon.svg101
-rwxr-xr-xdoc/images/icon_apps_blue.pngbin0 -> 6342 bytes
-rwxr-xr-xdoc/images/icongear.pngbin0 -> 10833 bytes
-rwxr-xr-xdoc/images/media_player_app_icon.pngbin0 -> 4347 bytes
-rwxr-xr-xdoc/images/media_player_app_icon.svg97
-rwxr-xr-xdoc/images/news_app_icon.pngbin0 -> 2428 bytes
-rwxr-xr-xdoc/images/news_app_icon.svg57
-rwxr-xr-xdoc/images/nfc_app_icon.pngbin0 -> 3933 bytes
-rwxr-xr-xdoc/images/nfc_app_icon.svg94
-rwxr-xr-xdoc/images/phone_app_icon.pngbin0 -> 4335 bytes
-rwxr-xr-xdoc/images/phone_app_icon.svg108
-rwxr-xr-xdoc/images/settings_icon.pngbin0 -> 6528 bytes
-rwxr-xr-xdoc/images/shift_off_icon.pngbin0 -> 825 bytes
-rwxr-xr-xdoc/images/shift_on_icon.pngbin0 -> 710 bytes
-rwxr-xr-xdoc/images/space_bar_icon.pngbin0 -> 302 bytes
-rwxr-xr-xdoc/images/switchcontrol.pngbin0 -> 2269 bytes
-rwxr-xr-xdoc/images/switchplate_off.pngbin0 -> 5071 bytes
-rwxr-xr-xdoc/images/switchplate_on.pngbin0 -> 4824 bytes
-rwxr-xr-xdoc/images/symbols_icon.pngbin0 -> 1373 bytes
-rwxr-xr-xdoc/images/symbols_off_icon.pngbin0 -> 1500 bytes
-rwxr-xr-xdoc/images/tizen.pngbin0 -> 4391 bytes
-rwxr-xr-xdoc/images/weather_app_icon.pngbin0 -> 4615 bytes
-rwxr-xr-xdoc/images/weather_app_icon.svg115
-rwxr-xr-xdoc/images/white_return.pngbin0 -> 728 bytes
-rwxr-xr-xexport.map1
-rwxr-xr-xicon_wifi_128.pngbin0 -> 18162 bytes
-rwxr-xr-ximports/components/AwesomeIcon.qml26
-rwxr-xr-ximports/components/Box.qml49
-rwxr-xr-ximports/components/BoxButton.qml36
-rwxr-xr-ximports/components/BoxHeading.qml37
-rwxr-xr-ximports/components/Button.qml30
-rwxr-xr-ximports/components/DateTime.qml35
-rwxr-xr-ximports/components/HexGrid.qml32
-rwxr-xr-ximports/components/HexSwitch.qml80
-rwxr-xr-ximports/components/InShadow.qml33
-rwxr-xr-ximports/components/InsetShadow.qml40
-rwxr-xr-ximports/components/Label.qml27
-rwxr-xr-ximports/components/NumberPad.qml101
-rwxr-xr-ximports/components/OutShadow.qml41
-rwxr-xr-ximports/components/Switch.qml13
-rwxr-xr-ximports/components/qmldir16
-rwxr-xr-ximports/radio/Radio.qml6
-rwxr-xr-ximports/radio/qmldir2
-rwxr-xr-ximports/system/App.qml29
-rwxr-xr-ximports/system/System.qml15
-rwxr-xr-ximports/system/qmldir8
-rwxr-xr-ximports/utils/Marker.qml60
-rwxr-xr-ximports/utils/Style.qml37
-rwxr-xr-ximports/utils/qmldir8
-rwxr-xr-ximports/vehicle/ClimateModel.qml44
-rwxr-xr-ximports/vehicle/FuelModel.qml46
-rwxr-xr-ximports/vehicle/PositionModel.qml33
-rwxr-xr-ximports/vehicle/SpeedModel.qml38
-rwxr-xr-ximports/vehicle/TemperatureModel.qml26
-rwxr-xr-ximports/vehicle/qmldir11
-rwxr-xr-xoe-sdk_crosscompile.cmake20
-rwxr-xr-xqml/wifi-settings/components/images/back.pngbin0 -> 1237 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi1-lock.pngbin0 -> 6083 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi1.pngbin0 -> 4934 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi2-lock.pngbin0 -> 6270 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi2.pngbin0 -> 5106 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi3-lock.pngbin0 -> 6204 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi3.pngbin0 -> 5125 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi4-lock.pngbin0 -> 5753 bytes
-rwxr-xr-xqml/wifi-settings/components/images/wifi4.pngbin0 -> 4622 bytes
-rwxr-xr-xqml/wifi-settings/wifi-settings-app.qml625
-rwxr-xr-xwifi-api.c489
-rwxr-xr-xwifi-api.h38
-rwxr-xr-xwifi-connman.c354
-rwxr-xr-xwifi-connman.h126
112 files changed, 5129 insertions, 0 deletions
diff --git a/AUTHORS.txt b/AUTHORS.txt
new file mode 100755
index 0000000..cd526f9
--- /dev/null
+++ b/AUTHORS.txt
@@ -0,0 +1,2 @@
+Milan Srdinko <msrdinko@alps.cz>
+Sri Maldia Hari Asti <hariasti.srimaldia-1@jp.alps.com> \ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100755
index 0000000..bbf3df8
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,68 @@
+project(wifi-settings)
+
+cmake_minimum_required(VERSION 3.3)
+
+include(GNUInstallDirs)
+
+set(PROJECT_VERSION "0.1")
+set(PROJECT_ICON "icon_wifi_128.png")
+set(PROJECT_LIBDIR "lib")
+set(PROJECT_QML "qml")
+set(PROJECT_IMPORT "imports")
+set(PROJECT_DOC "doc")
+
+set(CMAKE_BUILD_TYPE Debug)
+
+###########################################################################
+add_compile_options(-Wall -Wextra -Wconversion)
+add_compile_options(-Wno-unused-parameter) # frankly not using a parameter does it care?
+add_compile_options(-Werror=maybe-uninitialized)
+add_compile_options(-Werror=implicit-function-declaration)
+add_compile_options(-ffunction-sections -fdata-sections)
+add_compile_options(-Wl,--as-needed -Wl,--gc-sections)
+add_compile_options(-fPIC)
+
+set(CMAKE_C_FLAGS_PROFILING "-g -O0 -pg -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_DEBUG "-g -O0 -ggdb -Wp,-U_FORTIFY_SOURCE")
+set(CMAKE_C_FLAGS_RELEASE "-g -O2")
+set(CMAKE_C_FLAGS_CCOV "-g -O2 --coverage")
+
+###########################################################################
+
+include(FindPkgConfig)
+
+pkg_check_modules(EXTRAS REQUIRED json-c afb-daemon glib-2.0 gio-2.0 gobject-2.0 zlib)
+add_compile_options(${EXTRAS_CFLAGS})
+include_directories(${EXTRAS_INCLUDE_DIRS})
+link_libraries(${EXTRAS_LIBRARIES})
+
+###########################################################################
+# the binding for afb
+
+message(STATUS "Creation of ${PROJECT_NAME} for AFB-DAEMON")
+
+###############################################################
+add_library(${PROJECT_NAME} MODULE wifi-api.c wifi-connman.c agent.c)
+
+set_target_properties(${PROJECT_NAME} PROPERTIES
+ PREFIX ""
+ LINK_FLAGS "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/export.map"
+)
+
+configure_file(config.xml.in config.xml)
+
+add_custom_command(
+ OUTPUT ${PROJECT_NAME}.wgt
+ DEPENDS ${PROJECT_NAME}
+ COMMAND rm -rf package
+ COMMAND mkdir -p package/${PROJECT_LIBDIR} package/htdocs
+ COMMAND cp config.xml package/
+ COMMAND cp -rf ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_ICON} package/icon.png
+ COMMAND cp -rf ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_QML} package/${PROJECT_QML}
+ COMMAND cp -rf ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_IMPORT} package/${PROJECT_IMPORT}
+ COMMAND cp -rf ${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_DOC} package/${PROJECT_DOC}
+ COMMAND cp ${PROJECT_NAME}.so package/${PROJECT_LIBDIR}
+ COMMAND wgtpkg-pack -f -o ${PROJECT_NAME}.wgt package
+ COMMAND rm -rf package
+)
+add_custom_target(widget ALL DEPENDS ${PROJECT_NAME}.wgt)
diff --git a/LICENSE-2.0.txt b/LICENSE-2.0.txt
new file mode 100755
index 0000000..a396b36
--- /dev/null
+++ b/LICENSE-2.0.txt
@@ -0,0 +1,201 @@
+ 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. \ No newline at end of file
diff --git a/README.txt b/README.txt
new file mode 100755
index 0000000..8565b5a
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,34 @@
+##Wifi Manager
+This folder include wifi manager binding and GUI.
+Only support Station mode.
+
+##Function
+- Wifi ON and OFF
+- Wifi scan and display result
+- Connect to open and secured AccessPoint
+- Disconnect connection
+
+##Guidance for building Wi-Fi manager Binding
+A. Prepare sdk environment
+ - bitbake below:
+ $ bitbake agl-demo-platform-crosssdk
+ - install sdk
+ $ build/tmp/deploy/sdk/poky-agl-glibc*.sh
+B. Build
+ - Go to folder where WiFi Bindings source code exists
+ - run below command for setup and make
+ $ . /opt/poky-agl/xxx/environment-setup-cortexa15hf-vfp-neon-poky-linux-gnueabi
+ $ mkdir build
+ $ cmake ..
+ $ make
+ <widget wll be generated>
+C. Running app
+ - copy widget to porter board
+ - do install and start the app
+ # afm-util install *.wgt
+ # afm-util start <apps's name>@0.1
+
+##TODO
+- ADD token security
+- ADD event receive
+
diff --git a/agent.c b/agent.c
new file mode 100755
index 0000000..a22dc31
--- /dev/null
+++ b/agent.c
@@ -0,0 +1,262 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <stdio.h>
+#include <errno.h>
+
+#include <gio/gio.h>
+#include "wifi-connman.h"
+
+static GMainLoop *loop = NULL;
+
+static GDBusNodeInfo *introspection_data = NULL;
+
+GDBusMethodInvocation *invocation_passkey = NULL;
+
+/* Introspection data for the agent service */
+static const gchar introspection_xml[] = "<node>"
+ " <interface name='net.connman.Agent'>"
+ " <method name='RequestInput'>"
+ " <arg type='o' name='service' direction='in'/>"
+ " <arg type='a{sv}' name='fields' direction='in'/>"
+ " <arg type='a{sv}' name='fields' direction='out'/>"
+ " </method>"
+ " <method name='ReportError'>"
+ " <arg type='o' name='service' direction='in'/>"
+ " <arg type='s' name='error' direction='in'/>"
+ " </method>"
+ " </interface>"
+ "</node>";
+
+callback password_callback;
+
+static void handle_method_call(GDBusConnection *connection, const gchar *sender,
+ const gchar *object_path, const gchar *interface_name,
+ const gchar *method_name, GVariant *parameters,
+ GDBusMethodInvocation *invocation, gpointer user_data) {
+ //MyObject *myobj = user_data;
+
+ if (g_strcmp0(method_name, "RequestInput") == 0) {
+ printf("Input requested\n");
+
+ invocation_passkey = invocation;
+
+ //TODO: send the name of the network to callback
+
+ (*password_callback)(0);
+
+ GVariantIter *array;
+ gchar * object_path;
+ g_variant_get(parameters, "(oa{sv})", &object_path, &array);
+ //TODO: get only object path for now, complete parameters are
+
+ /*
+ object path "/net/connman/service/wifi_d85d4c880b1a_4c656e6f766f204b3520506c7573_managed_psk"
+ array [
+ dict entry(
+ string "Passphrase"
+ variant array [
+ dict entry(
+ string "Type"
+ variant string "psk"
+ )
+ dict entry(
+ string "Requirement"
+ variant string "mandatory"
+ )
+ ]
+ )
+ ]
+ */
+ printf("Passphrase requested for network : %s\n", object_path);
+
+ }
+
+ if (g_strcmp0(method_name, "ReportError") == 0) {
+ printf("Error reported\n");
+
+ gchar *error_string; // = NULL;
+
+ gchar * object_path;
+ g_variant_get(parameters, "(os)", &object_path, &error_string);
+
+ printf("Error %s for %s\n", error_string, object_path);
+
+ if (g_strcmp0(error_string, "invalid-key") == 0) {
+
+ printf("Passkey is not correct.\n");
+ (*password_callback)(1);
+
+ }
+
+ }
+}
+
+GError* sendPasskey(gchar *passkey) {
+
+ GVariantBuilder *builder;
+ GVariant *value = NULL;
+
+ printf("Passkey to send: %s\n", passkey);
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("a{sv}"));
+
+ g_variant_builder_add(builder, "{sv}", "Passphrase",
+ g_variant_new_string(passkey));
+
+ value = g_variant_new("(a{sv})", builder);
+
+ g_dbus_method_invocation_return_value(invocation_passkey, value);
+
+ return NULL;
+
+}
+
+static const GDBusInterfaceVTable interface_vtable = { handle_method_call, NULL,
+ NULL };
+
+static void on_bus_acquired(GDBusConnection *connection, const gchar *name,
+ gpointer user_data) {
+ //MyObject *myobj = user_data;
+ guint registration_id;
+
+ registration_id = g_dbus_connection_register_object(connection,
+ "/net/connman/Agent", introspection_data->interfaces[0],
+ &interface_vtable, NULL, NULL, /* user_data_free_func */
+ NULL); /* GError** */
+ //TODO: make some proper error message rather than exiting
+ //g_assert(registration_id > 0);
+
+ return NULL;
+}
+
+void* register_agent(void *data) {
+
+ //printf("Loop start\n");
+
+ guint owner_id;
+ //MyObject *myobj;
+
+ introspection_data = g_dbus_node_info_new_for_xml(introspection_xml, NULL);
+ g_assert(introspection_data != NULL);
+
+ //myobj = g_object_new(my_object_get_type(), NULL);
+
+// owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, "org.agent",
+// G_BUS_NAME_OWNER_FLAGS_NONE, on_bus_acquired, on_name_acquired,
+// on_name_lost, myobj,
+// NULL);
+
+//FIXME: ALLOW_REPLACEMENT for now, make proper deinitialization
+ owner_id = g_bus_own_name(G_BUS_TYPE_SYSTEM, AGENT_SERVICE,
+ G_BUS_NAME_OWNER_FLAGS_REPLACE, on_bus_acquired, NULL, NULL, NULL,
+ NULL);
+ //G_BUS_NAME_OWNER_FLAGS_NONE G_BUS_NAME_OWNER_FLAGS_ALLOW_REPLACEMENT
+
+ loop = g_main_loop_new(NULL, FALSE);
+
+ //sleep(10);
+ g_main_loop_run(loop);
+
+ printf("Loop running\n");
+
+ g_bus_unown_name(owner_id);
+
+ g_dbus_node_info_unref(introspection_data);
+
+ //g_object_unref(myobj);
+
+ //printf("Loop end\n");
+
+ return NULL;
+
+}
+
+GError* create_agent(GDBusConnection *connection) {
+
+ int err = -1;
+ pthread_t tid[1];
+
+ //struct callbackData *threadData;
+
+ err = pthread_create((&tid[0]), NULL, register_agent, NULL);
+
+ if (err != 0) {
+ printf("\ncan't create thread :[%d]", err);
+ printf("Fatal error!\n\n");
+ return NULL;
+ }
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+
+ GVariant *params = NULL;
+
+ char *agent_path = AGENT_PATH;
+
+ params = g_variant_new("(o)", agent_path);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "RegisterAgent", params,
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+
+ } else {
+ printf("Agent registered\n");
+ return NULL;
+ }
+
+}
+
+GError* stop_agent(GDBusConnection *connection) {
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+
+
+ GVariant *params = NULL;
+
+ char *agent_path = AGENT_PATH;
+
+
+ params = g_variant_new("(o)", agent_path);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "UnregisterAgent", params,
+ NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+ return error;
+
+ } else {
+ printf("Agent unregistered\n");
+ return NULL;
+ }
+
+}
+
+void register_callback(callback callback_function) {
+
+ password_callback = callback_function;
+
+}
+
diff --git a/config.xml.in b/config.xml.in
new file mode 100755
index 0000000..b403953
--- /dev/null
+++ b/config.xml.in
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<widget xmlns="http://www.w3.org/ns/widgets" id="@PROJECT_NAME@" version="@PROJECT_VERSION@">
+ <name>Wifi Settings</name>
+ <icon src="icon.png"/>
+ <content src="qml/@PROJECT_NAME@/@PROJECT_NAME@-app.qml" type="application/vnd.agl.qml.hybrid"/>
+ <description>Wifi Settings application</description>
+ <author>ALPS (Milan Srdinko &lt;msrdinko@alps.cz&gt;, Srimaldia Hariasti &lt;hariasti.srimaldia-1@jp.alps.com&gt;)</author>
+ <license>APL 2.0</license>
+</widget>
diff --git a/doc/AppGrid.qml b/doc/AppGrid.qml
new file mode 100755
index 0000000..46b7889
--- /dev/null
+++ b/doc/AppGrid.qml
@@ -0,0 +1,43 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import components 1.0
+import system 1.0
+
+App {
+ id: root
+ appId: 'appgrid'
+
+ HexGrid {
+ anchors.centerIn: parent
+ columns: 5
+ spacing: 10
+
+ Repeater {
+ model: ListModel {
+ ListElement { icon: "hvac"; name: "HVAC" }
+ ListElement { icon: "browser"; name: "DNA Browser" }
+ ListElement { icon: "dashboard"; name: "Dashboard" }
+ ListElement { icon: "googlemaps"; name: "Google Maps" }
+ ListElement { icon: "news"; name: "News" }
+ ListElement { icon: "nfc"; name: "NFC" }
+ ListElement { icon: "fmradio"; name: "FM Radio" }
+ ListElement { icon: "phone"; name: "Phone" }
+ ListElement { icon: "weather"; name: "Weather" }
+ ListElement { icon: "media_player"; name: "Media Manager" }
+ ListElement { icon: "cameras"; name: "Cameras" }
+ ListElement { icon: "fingerprint"; name: "Fingerprint" }
+ ListElement { icon: "wayland"; name: "Wayland" }
+ }
+ delegate: GridItem {
+ name: model.name
+ icon: model.icon
+ onClicked: System.activeApp = model.icon
+ }
+ }
+ }
+}
diff --git a/doc/AppIcon.qml b/doc/AppIcon.qml
new file mode 100755
index 0000000..b645ed9
--- /dev/null
+++ b/doc/AppIcon.qml
@@ -0,0 +1,51 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+MouseArea {
+ id: root
+
+ width: 90
+ height: 90
+
+ property bool active: false
+ property alias source: icon.source
+
+ function click() {
+ clicked(undefined)
+ }
+
+ Image {
+ id: icon
+ anchors.centerIn: parent
+ width: 100
+ height: 100
+ fillMode: Image.PreserveAspectFit
+ }
+
+// states: [
+// State {
+// name: "focused"
+// when: root.active
+// PropertyChanges {
+// target: icon
+// scale: 2.0
+// anchors.verticalCenterOffset: 20
+// }
+// }
+// ]
+
+// transitions: [
+// Transition {
+// NumberAnimation {
+// properties: 'scale, anchors.verticalCenterOffset'
+// easing.type: Easing.OutElastic
+// duration: 500
+// }
+// }
+// ]
+}
diff --git a/doc/BottomBar.qml b/doc/BottomBar.qml
new file mode 100755
index 0000000..0760b71
--- /dev/null
+++ b/doc/BottomBar.qml
@@ -0,0 +1,65 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import system 1.0
+//import com.pelagicore.qmldevinfo 0.1
+
+Item {
+ height: 120
+
+ ShaderEffect {
+ anchors.fill: parent
+ property color color: "#777"
+ property real radius: 40
+ opacity: 0.24
+
+ fragmentShader: "
+uniform lowp float radius;
+uniform lowp float height;
+uniform lowp float width;
+uniform lowp float qt_Opacity;
+uniform lowp vec4 color;
+varying highp vec2 qt_TexCoord0;
+
+void main(void) {
+ lowp vec2 dist = min(qt_TexCoord0, vec2(1.0) - qt_TexCoord0);
+ lowp float xval = smoothstep(0.0, radius, dist.x * width);
+ lowp float yval = smoothstep(0.0, radius, dist.y * height);
+ gl_FragColor = mix(color, vec4(1.0), sqrt(yval * xval)) * qt_Opacity;
+}
+ "
+ }
+
+ Image {
+ anchors.left: parent.left
+ anchors.verticalCenter: parent.verticalCenter
+ source: "images/settings_icon.png"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: System.showSettings = !System.showSettings
+ }
+ }
+
+// DevInfo {
+// id: devinfo
+// }
+
+ Image {
+ anchors.centerIn: parent
+ anchors.horizontalCenterOffset: -15
+ source: "images/AGL-Logo.png"
+ height: 80
+ fillMode: Image.PreserveAspectFit
+ }
+
+ VolumeControl {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.right: parent.right
+ anchors.rightMargin: 40
+ }
+}
diff --git a/doc/GridItem.qml b/doc/GridItem.qml
new file mode 100755
index 0000000..93d3031
--- /dev/null
+++ b/doc/GridItem.qml
@@ -0,0 +1,45 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ id: root
+
+ width: background.width
+ height: background.height
+
+ property string name
+ property string icon
+
+ signal clicked()
+
+ Image {
+ id: background
+ source: "images/AppHex.png"
+ }
+
+ Column {
+ y: 10
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: -10
+
+ AppIcon {
+ source: "images/%1_app_icon.png".arg(root.icon)
+ }
+
+ Text {
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: "white"
+ text: root.name
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.clicked()
+ }
+}
diff --git a/doc/Key.qml b/doc/Key.qml
new file mode 100755
index 0000000..6eb5ae0
--- /dev/null
+++ b/doc/Key.qml
@@ -0,0 +1,85 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+import utils 1.0
+
+Item {
+ id: root
+
+ width: 90
+ height: 130
+
+ property color color: Style.orangeViv
+ property alias text: textItem.text
+ property alias symbol: symbolItem.text
+ property real fade: 0.16
+ property string icon: ""
+
+ signal clicked()
+
+ Rectangle {
+ id: keyRect
+ anchors.fill: parent
+ radius: 10
+ }
+
+ LinearGradient {
+ anchors.fill: parent
+ source: keyRect
+ start: Qt.point(0, 0)
+ end: Qt.point(0, 130)
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: root.color }
+ GradientStop { position: root.fade; color: Qt.darker(root.color, 2.0) }
+ GradientStop { position: 0.8; color: "black" }
+ }
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "transparent"
+ radius: 10
+ border.width: 4
+ border.color: Style.orangeLt
+
+ Text {
+ id: symbolItem
+ visible: icon === ""
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.topMargin: 15
+ anchors.rightMargin: 20
+ font.pixelSize: 28
+ font.family: "Source Sans Pro"
+ color: "white"
+ }
+
+ Text {
+ id: textItem
+ visible: icon === ""
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 10
+ font.pixelSize: 60
+ font.family: "Source Sans Pro"
+ color: "white"
+ }
+
+ Image {
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 30
+ source: icon === "" ? icon : "images/" + icon + ".png"
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.clicked()
+ }
+}
diff --git a/doc/Keyboard.qml b/doc/Keyboard.qml
new file mode 100755
index 0000000..be79b75
--- /dev/null
+++ b/doc/Keyboard.qml
@@ -0,0 +1,137 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ id: root
+ height: 620
+
+ property var currentString: ""
+ property bool useSymbols: false
+ property bool useUppercase: false
+
+ property var rows: [
+ ["q","w","e","r","t","y","u","i","o","p"],
+ ["a","s","d","f","g","h","j","k","l"],
+ ["z","x","c","v","b","n","m"]
+ ]
+ property var symbolRows: [
+ ["1","2","3","4","5","6","7","8","9","0"],
+ ["(",")","-","@","*","^",":",";","~"],
+ ["/","'","\"",".",",","?","!"]
+ ]
+
+ function keyPressed(text, symbol) {
+ if (useSymbols)
+ currentString += symbol
+ else
+ currentString += text
+ }
+
+ Rectangle {
+ anchors.fill: parent
+ color: "black"
+ opacity: 0.7
+ }
+
+ Column {
+ y: 20
+ width: parent.width
+ spacing: 20
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Repeater {
+ model: rows[0]
+ Key {
+ text: useUppercase ? modelData.toUpperCase() : modelData
+ symbol: symbolRows[0][index]
+ onClicked: keyPressed(text, symbol)
+ }
+ }
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 10
+
+ Repeater {
+ model: rows[1]
+ Key {
+ text: useUppercase ? modelData.toUpperCase() : modelData
+ symbol: symbolRows[1][index]
+ onClicked: keyPressed(text, symbol)
+ }
+ }
+ }
+
+ Row {
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 45
+
+ Key {
+ width: 130
+ color: Style.orangeLt
+ fade: 0.3
+ icon: "shift_" + (useUppercase ? "on" : "off") + "_icon"
+ onClicked: useUppercase = !useUppercase
+ }
+
+ Row {
+ spacing: 10
+
+ Repeater {
+ model: rows[2]
+ Key {
+ text: useUppercase ? modelData.toUpperCase() : modelData
+ symbol: symbolRows[2][index]
+ onClicked: keyPressed(text, symbol)
+ }
+ }
+ }
+
+ Key {
+ width: 130
+ color: Style.orangeLt
+ fade: 0.3
+ icon: "backspace_icon"
+ onClicked: currentString = currentString.slice(0, -1)
+ }
+ }
+
+ Row {
+ spacing: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ Key {
+ width: 150
+ color: Style.orangeLt
+ fade: 0.3
+ icon: "symbols" + (useSymbols ? "" : "_off") + "_icon"
+ onClicked: useSymbols = !useSymbols
+ }
+
+ Key {
+ width: 700
+ color: Style.orangeLt
+ fade: 0.3
+ icon: "space_bar_icon"
+ onClicked: keyPressed(" ", " ")
+ }
+
+ Key {
+ width: 150
+ color: Style.orangeLt
+ fade: 0.3
+ icon: "white_return"
+ }
+ }
+ }
+}
diff --git a/doc/Main.qml b/doc/Main.qml
new file mode 100755
index 0000000..8f92511
--- /dev/null
+++ b/doc/Main.qml
@@ -0,0 +1,101 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.3
+import "apps/Browser"
+import "apps/Cameras"
+import "apps/Dashboard"
+import "apps/Fingerprint"
+import "apps/FMRadio"
+import "apps/GoogleMaps"
+import "apps/Home"
+import "apps/HVAC"
+import "apps/MediaPlayer"
+import "apps/News"
+import "apps/NFC"
+import "apps/Phone"
+import "apps/Settings"
+import "apps/Weather"
+import "apps/WaylandView"
+import system 1.0
+
+Item {
+ width: 1080
+ height: 1920
+
+ Image {
+ anchors.centerIn: parent
+ source: "images/Hex-Background.jpg"
+ }
+
+ Item {
+ id: appSurface
+
+ anchors.top: topbar.bottom
+ anchors.bottom: bottombar.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+
+ Home {}
+ GoogleMaps {}
+ Browser {}
+ Dashboard {}
+ HVAC {}
+ Weather {}
+ FMRadio {}
+ MediaPlayer {}
+ NFC {}
+ News {}
+ Phone {}
+ WaylandView {}
+ Cameras {}
+ Fingerprint {}
+ AppGrid {}
+ }
+
+ TopBar {
+ id: topbar
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+
+ BottomBar {
+ id: bottombar
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+ }
+
+ Settings {
+ id: settings
+ visible: System.showSettings
+ anchors.fill: parent
+ anchors.topMargin: 120
+ anchors.bottomMargin: 120
+ }
+
+ Keyboard {
+ id: keyboard
+ y: System.showKeyboard ? parent.height - height : parent.height
+ width: parent.width
+
+ Behavior on y { YAnimator { duration: 300; easing.type: Easing.OutQuad }}
+ }
+
+ focus: true
+ Keys.onLeftPressed: topbar.left()
+ Keys.onRightPressed: topbar.right()
+ Keys.onReturnPressed: topbar.click()
+ Keys.onBackPressed: topbar.home()
+ Keys.onPressed: {
+ switch (event.key) {
+ default:
+ console.debug('Main.qml', event.key)
+ }
+ }
+}
diff --git a/doc/README.md b/doc/README.md
new file mode 100755
index 0000000..b01fc55
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,23 @@
+Open source QML UI
+
+To run on target:
+$ cd /usr/AGL/CES2017
+$ /usr/bin/qt5/qmlscene -I imports Main.qml
+
+For development it can be nice to use Scaled.qml instead so it fits your screen.
+
+
+
+© 2015 Jaguar Land Rover. All Rights Reserved.
+Licensed under Creative Commons Attribution 4.0 International
+https://creativecommons.org/licenses/by/4.0/legalcode
+
+(Optional) switch shell for weston to ivi-shell and start demo apps if you want to start demo apps with ivi-shell.
+$ cd /usr/AGL/CES2017
+$ ./switch_to_ivi-shell
+(Option a) $ ./start_ALS2016_ivi-shell.sh
+(Option b) $ ./start_ALS2016_with_navi_ivi-shell.sh
+
+Option a: start QML UI only.
+Option b: start QML + CarNavigation:/home/navi. For the time being, CarNavigation expects to be Wayland native application, which will be showed on top of QML by using LayerManagerControl.
+
diff --git a/doc/Rotated.qml b/doc/Rotated.qml
new file mode 100755
index 0000000..4eef7f3
--- /dev/null
+++ b/doc/Rotated.qml
@@ -0,0 +1,17 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ width: 1920
+ height: 1080
+
+ Main {
+ anchors.centerIn: parent
+ rotation: 90
+ }
+}
diff --git a/doc/Scaled.qml b/doc/Scaled.qml
new file mode 100755
index 0000000..c566735
--- /dev/null
+++ b/doc/Scaled.qml
@@ -0,0 +1,17 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ width: 1080*scale
+ height: 1920*scale
+ scale: 0.5
+
+ Main {
+ anchors.centerIn: parent
+ }
+}
diff --git a/doc/Scaled_04.qml b/doc/Scaled_04.qml
new file mode 100755
index 0000000..502a663
--- /dev/null
+++ b/doc/Scaled_04.qml
@@ -0,0 +1,17 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ width: 1080*scale
+ height: 1920*scale
+ scale: 0.4
+
+ Main {
+ anchors.centerIn: parent
+ }
+}
diff --git a/doc/Scaled_720p.qml b/doc/Scaled_720p.qml
new file mode 100755
index 0000000..86cb9b1
--- /dev/null
+++ b/doc/Scaled_720p.qml
@@ -0,0 +1,17 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ width: 1080*scale
+ height: 1920*scale
+ scale: 0.666666666
+
+ Main {
+ anchors.centerIn: parent
+ }
+}
diff --git a/doc/TopBar.qml b/doc/TopBar.qml
new file mode 100755
index 0000000..5e0a532
--- /dev/null
+++ b/doc/TopBar.qml
@@ -0,0 +1,146 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import system 1.0
+import execScript 1.0
+
+Item {
+ id: root
+
+ height: 120
+
+ ShaderEffect {
+ anchors.fill: parent
+ property color color: "#777"
+ property real radius: 40
+ opacity: 0.24
+
+ fragmentShader: "
+uniform lowp float radius;
+uniform lowp float height;
+uniform lowp float width;
+uniform lowp float qt_Opacity;
+uniform lowp vec4 color;
+varying highp vec2 qt_TexCoord0;
+
+void main(void) {
+ lowp vec2 dist = min(qt_TexCoord0, vec2(1.0) - qt_TexCoord0);
+ lowp float xval = smoothstep(0.0, radius, dist.x * width);
+ lowp float yval = smoothstep(0.0, radius, dist.y * height);
+ gl_FragColor = mix(color, vec4(1.0), sqrt(yval * xval)) * qt_Opacity;
+}
+ "
+ }
+
+ property int currentIndex: 0
+ property AppIcon currentItem
+
+ Row {
+ anchors.verticalCenter: parent.verticalCenter
+ anchors.verticalCenterOffset: 5
+ anchors.horizontalCenter: parent.horizontalCenter
+ spacing: 30
+
+ AppIcon {
+ id: homeScreen
+ active: currentIndex === 0
+ onActiveChanged: if (active) root.currentItem = homeScreen
+ property var mainScreen: root.parent
+ property bool home: System.activeApp === "home"
+ source: home ? "images/agl_icon.png" : "images/homescreen_icon.png"
+
+ onClicked: {
+ if (currentIndex === 1) {
+ execscript.execute("./switch_off_navi.sh")
+ }
+ currentIndex = 0
+ System.activeApp = "home"
+ }
+ }
+
+ AppIcon {
+ id: googleMaps
+ active: currentIndex === 1
+ onActiveChanged: if (active) root.currentItem = googleMaps
+ source: "images/googlemaps_app_icon.png"
+
+ onClicked: {
+ currentIndex = 1
+ System.activeApp = "googlemaps"
+ execscript.execute("./switch_on_navi.sh")
+ }
+ }
+
+ Repeater {
+ model: ListModel {
+ id: applicationModel
+ ListElement { name: "browser" }
+ ListElement { name: "dashboard" }
+ ListElement { name: "hvac" }
+ ListElement { name: "weather" }
+ ListElement { name: "fmradio" }
+ ListElement { name: "media_player" }
+ }
+
+ delegate: AppIcon {
+ id: app
+ active: currentIndex === model.index + 2
+ onActiveChanged: if (active) root.currentItem = app
+ source: "images/%1_app_icon.png".arg(model.name)
+ onClicked: {
+ if (currentIndex === 1) {
+ execscript.execute("./switch_off_navi.sh")
+ }
+ System.activeApp = model.name
+ currentIndex = model.index + 2
+ }
+
+ Rectangle {
+ x: -15.5
+ y: -15
+ height: 123
+ width: 1
+ color: "black"
+ }
+ }
+ }
+
+ AppIcon {
+ id: launcher
+ active: currentIndex === applicationModel.count + 2
+ onActiveChanged: if (active) root.currentItem = launcher
+ source: "images/application_grid.png"
+ onClicked: {
+ if (currentIndex === 1) {
+ execscript.execute("./switch_off_navi.sh")
+ }
+ System.activeApp = "appgrid"
+ currentIndex = applicationModel.count + 2
+ }
+ }
+ }
+
+ property int __appCount: applicationModel.count + 3
+
+ function left() {
+ root.currentIndex = (root.currentIndex + root.__appCount - 1) % root.__appCount
+ }
+
+ function right() {
+ root.currentIndex = (root.currentIndex + 1) % root.__appCount
+ }
+
+ function click() {
+ currentItem.click()
+ }
+
+ function home() {
+ homeScreen.click()
+ }
+
+ ExecScript { id: execscript }
+}
diff --git a/doc/VolumeControl.qml b/doc/VolumeControl.qml
new file mode 100755
index 0000000..56540a8
--- /dev/null
+++ b/doc/VolumeControl.qml
@@ -0,0 +1,97 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ height: 100
+ width: childrenRect.width
+
+ property alias value: shader.value
+
+ FontLoader {
+ source: "fontawesome-webfont.ttf"
+ }
+
+ Row {
+ spacing: 28
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ font.family: "FontAwesome"
+ font.pixelSize: 30
+ color: "white"
+ text: "\uf068"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: shader.value = Math.max(shader.value - 0.1, 0.0)
+ }
+ }
+
+ ShaderEffect {
+ id: shader
+ width: 85
+ height: 100
+
+ property color bgColor: "#333"
+ property color fgColor: "#b2f0ff"
+ property real value: 0.5
+
+ fragmentShader: "
+uniform lowp float qt_Opacity;
+uniform lowp float value;
+uniform lowp vec4 bgColor;
+uniform lowp vec4 fgColor;
+varying highp vec2 qt_TexCoord0;
+
+void main(void) {
+ lowp float x = min(qt_TexCoord0.x, 1.0 - qt_TexCoord0.x);
+ lowp float y = min(qt_TexCoord0.y, 1.0 - qt_TexCoord0.y);
+ lowp float c = y - 0.5 * (0.5 - x);
+ lowp float outside = smoothstep(0.0, 0.01, c);
+ lowp float rim = smoothstep(0.1, 0.11, c - step(x, 0.101));
+ lowp float inside = smoothstep(0.125, 0.135, c - step(x, 0.125));
+
+ lowp vec4 color = mix(bgColor, fgColor, step(qt_TexCoord0.x, value));
+ color = mix(color, bgColor, inside * 0.8);
+ color = mix(color, vec4(1.0), (rim - inside) * 0.6);
+
+ gl_FragColor = mix(vec4(0.0), color, outside) * qt_Opacity;
+}
+ "
+
+ MouseArea {
+ anchors.fill: parent
+ onPositionChanged: {
+ shader.value = Math.min(Math.max(mouse.x / width, 0.0), 1.0)
+ }
+ }
+
+ Text {
+ anchors.centerIn: parent
+ font.family: "Source Sans Pro"
+ font.weight: Font.Bold
+ font.pixelSize: 30
+ color: "white"
+ text: Math.round(shader.value * 100)
+ }
+ }
+
+ Text {
+ anchors.verticalCenter: parent.verticalCenter
+ font.family: "FontAwesome"
+ font.pixelSize: 30
+ color: "white"
+ text: "\uf067"
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: shader.value = Math.min(shader.value + 0.1, 1.0)
+ }
+ }
+ }
+}
diff --git a/doc/images/AGL-Logo.png b/doc/images/AGL-Logo.png
new file mode 100755
index 0000000..e869d7f
--- /dev/null
+++ b/doc/images/AGL-Logo.png
Binary files differ
diff --git a/doc/images/AppHex.png b/doc/images/AppHex.png
new file mode 100755
index 0000000..6c9aa68
--- /dev/null
+++ b/doc/images/AppHex.png
Binary files differ
diff --git a/doc/images/Hex-Background.jpg b/doc/images/Hex-Background.jpg
new file mode 100755
index 0000000..ac9bae0
--- /dev/null
+++ b/doc/images/Hex-Background.jpg
Binary files differ
diff --git a/doc/images/JLR-Logo.png b/doc/images/JLR-Logo.png
new file mode 100755
index 0000000..50887d1
--- /dev/null
+++ b/doc/images/JLR-Logo.png
Binary files differ
diff --git a/doc/images/agl_icon.png b/doc/images/agl_icon.png
new file mode 100755
index 0000000..ad36a0d
--- /dev/null
+++ b/doc/images/agl_icon.png
Binary files differ
diff --git a/doc/images/application_grid.png b/doc/images/application_grid.png
new file mode 100755
index 0000000..0cc5b2b
--- /dev/null
+++ b/doc/images/application_grid.png
Binary files differ
diff --git a/doc/images/backspace_icon.png b/doc/images/backspace_icon.png
new file mode 100755
index 0000000..6bc0f20
--- /dev/null
+++ b/doc/images/backspace_icon.png
Binary files differ
diff --git a/doc/images/blank_hexagon.png b/doc/images/blank_hexagon.png
new file mode 100755
index 0000000..afeb31f
--- /dev/null
+++ b/doc/images/blank_hexagon.png
Binary files differ
diff --git a/doc/images/browser_app_icon.png b/doc/images/browser_app_icon.png
new file mode 100755
index 0000000..9c6ec36
--- /dev/null
+++ b/doc/images/browser_app_icon.png
Binary files differ
diff --git a/doc/images/browser_app_icon.svg b/doc/images/browser_app_icon.svg
new file mode 100755
index 0000000..14d0ae6
--- /dev/null
+++ b/doc/images/browser_app_icon.svg
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="Browser_Icon">
+ <g id="world">
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <path style="fill:#FFFFFF;" d="M36,6C19.431,6,6,19.431,6,36c0,16.568,13.431,30,30,30c16.568,0,30-13.432,30-30
+ C66,19.431,52.568,6,36,6z M62.082,35.032H50.475c-0.106-4.287-0.871-8.382-2.221-12.132c2.614-1.09,5.028-2.54,7.231-4.252
+ C59.398,23.044,61.849,28.751,62.082,35.032z M34.93,62.076c-3.217-2.68-5.915-6.158-7.89-10.195
+ c2.534-0.795,5.217-1.229,7.992-1.315v11.516C34.998,62.082,34.964,62.076,34.93,62.076z M37.066,9.925
+ c3.652,3.04,6.631,7.109,8.645,11.856c-2.76,0.943-5.693,1.491-8.746,1.588V9.919C37.002,9.921,37.033,9.922,37.066,9.925z
+ M40.291,10.255c5.339,0.888,10.135,3.383,13.864,6.994c-2.024,1.555-4.241,2.871-6.633,3.867
+ C45.76,16.941,43.287,13.25,40.291,10.255z M35.032,9.919v13.45c-3.053-0.1-5.986-0.645-8.743-1.588
+ c2.015-4.747,4.993-8.816,8.642-11.856C34.965,9.922,34.998,9.921,35.032,9.919z M24.476,21.118
+ c-2.391-0.996-4.606-2.313-6.633-3.867c3.729-3.612,8.524-6.106,13.866-6.995C28.708,13.25,26.239,16.941,24.476,21.118z
+ M25.559,23.566c2.982,1.035,6.163,1.639,9.474,1.74v9.726H23.461C23.565,30.979,24.281,27.104,25.559,23.566z M35.032,36.968
+ v11.661c-3.053,0.094-6.003,0.593-8.786,1.488c-1.673-3.989-2.664-8.436-2.785-13.149H35.032z M31.709,61.744
+ c-4.787-0.793-9.133-2.878-12.667-5.906c1.906-1.324,3.967-2.438,6.17-3.291C26.899,56.047,29.108,59.152,31.709,61.744z
+ M36.969,62.082V50.566c2.77,0.09,5.457,0.521,7.992,1.315c-1.979,4.039-4.674,7.516-7.891,10.195
+ C37.039,62.076,37.002,62.082,36.969,62.082z M46.789,52.547c2.199,0.852,4.26,1.973,6.168,3.291
+ c-3.533,3.025-7.881,5.113-12.666,5.906C42.889,59.152,45.098,56.047,46.789,52.547z M45.752,50.117
+ c-2.781-0.896-5.734-1.395-8.783-1.488V36.968h11.57C48.418,41.682,47.429,46.128,45.752,50.117z M36.969,35.032v-9.726
+ c3.307-0.101,6.486-0.703,9.471-1.738c1.276,3.54,1.992,7.414,2.1,11.466h-11.57V35.032z M16.517,18.648
+ c2.203,1.712,4.62,3.162,7.229,4.252c-1.352,3.75-2.114,7.845-2.221,12.132H9.921C10.15,28.751,12.601,23.044,16.517,18.648z
+ M9.921,36.968h11.604c0.119,4.942,1.152,9.616,2.907,13.813c-2.452,0.955-4.737,2.23-6.846,3.738
+ C13.043,49.994,10.173,43.813,9.921,36.968z M54.412,54.514c-2.109-1.502-4.394-2.777-6.849-3.733
+ c1.757-4.198,2.79-8.87,2.911-13.814h11.607C61.826,43.813,58.959,49.994,54.412,54.514z"/>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/bt_close.png b/doc/images/bt_close.png
new file mode 100755
index 0000000..51ace79
--- /dev/null
+++ b/doc/images/bt_close.png
Binary files differ
diff --git a/doc/images/cameras_app_icon.png b/doc/images/cameras_app_icon.png
new file mode 100755
index 0000000..2127f8e
--- /dev/null
+++ b/doc/images/cameras_app_icon.png
Binary files differ
diff --git a/doc/images/cameras_app_icon.svg b/doc/images/cameras_app_icon.svg
new file mode 100755
index 0000000..d8d1610
--- /dev/null
+++ b/doc/images/cameras_app_icon.svg
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="Camera_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <path style="fill:#FFFFFF;" d="M18.552,31.609l-7.275-12.6c5.056-7.359,13.07-12.08,21.991-12.885L18.552,31.609z M8.755,23.424
+ C6.926,27.371,6,31.599,6,36.001c0,4.481,1.006,8.901,2.92,12.912h14.553L8.755,23.424z M60.504,18.695
+ C55.33,11.368,47.235,6.79,38.351,6.098l-7.274,12.598H60.504z M11.49,53.304c5.178,7.327,13.276,11.911,22.157,12.599
+ l7.273-12.599H11.49z M38.732,65.879c8.922-0.807,16.935-5.523,21.991-12.887l-7.275-12.6L38.732,65.879z M63.078,23.086H48.525
+ l14.718,25.495C65.073,44.632,66,40.405,66,36.001C66,31.519,64.994,27.101,63.078,23.086z"/>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/dashboard_app_icon.png b/doc/images/dashboard_app_icon.png
new file mode 100755
index 0000000..f7085d6
--- /dev/null
+++ b/doc/images/dashboard_app_icon.png
Binary files differ
diff --git a/doc/images/dashboard_app_icon.svg b/doc/images/dashboard_app_icon.svg
new file mode 100755
index 0000000..ca1146a
--- /dev/null
+++ b/doc/images/dashboard_app_icon.svg
@@ -0,0 +1,130 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="Dashboard_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,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
+J8AAZyBF33xNeFYAAAAASUVORK5CYII=" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M21.141,9.952c7.143-4.077,15.258-4.9,22.621-2.927C51.176,9.012,57.832,13.827,61.974,21
+ c0.027,0.046,0.052,0.092,0.075,0.139c4.077,7.144,4.899,15.259,2.926,22.623C62.987,51.177,58.174,57.833,51,61.974
+ c-0.046,0.027-0.094,0.052-0.141,0.075c-7.143,4.077-15.258,4.899-22.622,2.926C20.824,62.988,14.167,58.174,10.026,51
+ C10,50.954,9.975,50.906,9.951,50.859c-4.076-7.142-4.898-15.257-2.926-22.622C9.012,20.825,13.827,14.168,21,10.026
+ C21.046,10,21.094,9.975,21.141,9.952L21.141,9.952z M42.592,11.403c-6.261-1.677-13.156-0.983-19.217,2.476
+ c-0.035,0.023-0.069,0.044-0.105,0.064c-6.091,3.517-10.178,9.169-11.866,15.465c-1.678,6.262-0.983,13.156,2.474,19.218
+ c0.023,0.034,0.044,0.069,0.066,0.105c3.517,6.09,9.169,10.178,15.465,11.865c6.262,1.678,13.155,0.982,19.218-2.475
+ c0.033-0.022,0.069-0.044,0.104-0.066c6.091-3.516,10.179-9.168,11.866-15.464c1.678-6.263,0.982-13.157-2.476-19.218
+ c-0.023-0.034-0.044-0.07-0.065-0.106C54.54,17.179,48.889,13.091,42.592,11.403L42.592,11.403z"/>
+ <path style="fill:#FFFFFF;" d="M25.477,17.772c7.013-4.051,15.39-3.602,21.792,0.447l-8.057,6.356
+ c-2.232-1.233-4.799-1.936-7.531-1.936c-8.618,0-15.606,6.987-15.606,15.606c0,1.651,0.257,3.242,0.733,4.736l0.003,0.012
+ l-0.549,0.319C12.748,33.865,16.452,22.982,25.477,17.772L25.477,17.772z M53.742,24.679c0.167,0.261,0.329,0.526,0.485,0.798
+ c2.913,5.044,3.498,10.794,2.092,16.007l-9.053-2.432c0.089-1.771-0.117-3.545-0.621-5.247L53.742,24.679L53.742,24.679z"/>
+ <path style="fill:#FFFFFF;" d="M50.839,50.84c-1.958,1.96-4.279,3.495-6.816,4.546c-2.529,1.048-5.253,1.602-8.023,1.602
+ c-2.771,0-5.494-0.554-8.024-1.602c-2.537-1.051-4.858-2.586-6.816-4.546l3.209-3.207c1.551,1.551,3.365,2.757,5.328,3.569
+ c1.969,0.817,4.109,1.249,6.303,1.249c2.194,0,4.333-0.433,6.302-1.249c1.964-0.813,3.777-2.018,5.329-3.569L50.839,50.84
+ L50.839,50.84z"/>
+ <path style="fill:#FFFFFF;" d="M36.586,30.499l12.938-10.204c1.607-1.268,3.395,0.514,2.144,2.124L41.498,35.498
+ c0.243,2.628-1.428,5.13-4.061,5.845c-2.948,0.801-5.99-0.941-6.791-3.891c-0.8-2.95,0.942-5.99,3.891-6.79
+ C35.226,30.475,35.917,30.427,36.586,30.499L36.586,30.499z M35.326,33.569c1.345-0.365,2.729,0.428,3.094,1.772
+ c0.365,1.343-0.428,2.729-1.772,3.093c-1.344,0.364-2.729-0.43-3.092-1.772C33.19,35.319,33.984,33.933,35.326,33.569
+ L35.326,33.569z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M21.141,9.952c7.143-4.077,15.258-4.9,22.621-2.927C51.176,9.012,57.832,13.827,61.974,21
+ c0.027,0.046,0.052,0.092,0.075,0.139c4.077,7.144,4.899,15.259,2.926,22.623C62.987,51.177,58.174,57.833,51,61.974
+ c-0.046,0.027-0.094,0.052-0.141,0.075c-7.143,4.077-15.258,4.899-22.622,2.926C20.824,62.988,14.167,58.174,10.026,51
+ C10,50.954,9.975,50.906,9.951,50.859c-4.076-7.142-4.898-15.257-2.926-22.622C9.012,20.825,13.827,14.168,21,10.026
+ C21.046,10,21.094,9.975,21.141,9.952L21.141,9.952z M42.592,11.403c-6.261-1.677-13.156-0.983-19.217,2.476
+ c-0.035,0.023-0.069,0.044-0.105,0.064c-6.091,3.517-10.178,9.169-11.866,15.465c-1.678,6.262-0.983,13.156,2.474,19.218
+ c0.023,0.034,0.044,0.069,0.066,0.105c3.517,6.09,9.169,10.178,15.465,11.865c6.262,1.678,13.155,0.982,19.218-2.475
+ c0.033-0.022,0.069-0.044,0.104-0.066c6.091-3.516,10.179-9.168,11.866-15.464c1.678-6.263,0.982-13.157-2.476-19.218
+ c-0.023-0.034-0.044-0.07-0.065-0.106C54.54,17.179,48.889,13.091,42.592,11.403L42.592,11.403z"/>
+ <path style="fill:#FFFFFF;" d="M25.477,17.772c7.013-4.051,15.39-3.602,21.792,0.447l-8.057,6.356
+ c-2.232-1.233-4.799-1.936-7.531-1.936c-8.618,0-15.606,6.987-15.606,15.606c0,1.651,0.257,3.242,0.733,4.736l0.003,0.012
+ l-0.549,0.319C12.748,33.865,16.452,22.982,25.477,17.772L25.477,17.772z M53.742,24.679c0.167,0.261,0.329,0.526,0.485,0.798
+ c2.913,5.044,3.498,10.794,2.092,16.007l-9.053-2.432c0.089-1.771-0.117-3.545-0.621-5.247L53.742,24.679L53.742,24.679z"/>
+ <path style="fill:#FFFFFF;" d="M50.839,50.84c-1.958,1.96-4.279,3.495-6.816,4.546c-2.529,1.048-5.253,1.602-8.023,1.602
+ c-2.771,0-5.494-0.554-8.024-1.602c-2.537-1.051-4.858-2.586-6.816-4.546l3.209-3.207c1.551,1.551,3.365,2.757,5.328,3.569
+ c1.969,0.817,4.109,1.249,6.303,1.249c2.194,0,4.333-0.433,6.302-1.249c1.964-0.813,3.777-2.018,5.329-3.569L50.839,50.84
+ L50.839,50.84z"/>
+ <path style="fill:#FFFFFF;" d="M36.586,30.499l12.938-10.204c1.607-1.268,3.395,0.514,2.144,2.124L41.498,35.498
+ c0.243,2.628-1.428,5.13-4.061,5.845c-2.948,0.801-5.99-0.941-6.791-3.891c-0.8-2.95,0.942-5.99,3.891-6.79
+ C35.226,30.475,35.917,30.427,36.586,30.499L36.586,30.499z M35.326,33.569c1.345-0.365,2.729,0.428,3.094,1.772
+ c0.365,1.343-0.428,2.729-1.772,3.093c-1.344,0.364-2.729-0.43-3.092-1.772C33.19,35.319,33.984,33.933,35.326,33.569
+ L35.326,33.569z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/fingerprint_app_icon.png b/doc/images/fingerprint_app_icon.png
new file mode 100755
index 0000000..abea688
--- /dev/null
+++ b/doc/images/fingerprint_app_icon.png
Binary files differ
diff --git a/doc/images/fmradio_app_icon.png b/doc/images/fmradio_app_icon.png
new file mode 100755
index 0000000..b781d31
--- /dev/null
+++ b/doc/images/fmradio_app_icon.png
Binary files differ
diff --git a/doc/images/fmradio_app_icon.svg b/doc/images/fmradio_app_icon.svg
new file mode 100755
index 0000000..5442afe
--- /dev/null
+++ b/doc/images/fmradio_app_icon.svg
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 71.04 72.48" style="enable-background:new 0 0 71.04 72.48;" xml:space="preserve">
+<g id="FM_Radio_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="71" height="73" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 0.5 -0.52)">
+ </image>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M12.492,23.967h6.384c0.729,0,1.324-0.596,1.324-1.325v-1.873c0-0.731-0.595-1.326-1.324-1.326
+ H17.19v-4.776c0.256-0.092-0.449,0.346,0.754-0.349c1.202-0.692,2.9-4.012,1.652-6.173c-1.246-2.161-4.01-2.901-6.171-1.654
+ c-2.162,1.248-2.903,4.013-1.656,6.173c0.563,0.972,1.431,1.656,2.409,2.002v4.777h-1.686c-0.731,0-1.325,0.595-1.325,1.326
+ v1.873C11.167,23.372,11.762,23.967,12.492,23.967z"/>
+ <path style="fill:#FFFFFF;" d="M24.538,23.966h1.865c0.731,0,1.327-0.596,1.327-1.325v-0.368c0-0.73,0.594-1.325,1.325-1.325
+ h19.937c0.73,0,1.325,0.595,1.325,1.325v0.368c0,0.729,0.596,1.325,1.326,1.325h1.865c0.729,0,1.325-0.596,1.325-1.325v-0.909
+ c0-2.921-2.38-5.302-5.3-5.304c-7.324,0-13.696,0-21.022,0c-2.92,0-5.3,2.383-5.3,5.304v0.909
+ C23.213,23.371,23.81,23.966,24.538,23.966z"/>
+ <circle style="fill:#FFFFFF;" cx="23.213" cy="43.543" r="4.495"/>
+ <path style="fill:#FFFFFF;" d="M52.725,26.973h-39.45v0.001c-3.649,0-6.626,2.978-6.626,6.629v19.885
+ c0,3.65,2.979,6.628,6.626,6.628h39.45c3.649,0,6.627-2.978,6.627-6.628V33.601C59.352,29.952,56.374,26.973,52.725,26.973z
+ M44.296,34.326c0-0.732,0.593-1.325,1.325-1.325h0.359c0.73,0,1.326,0.597,1.326,1.325v0.361c0,0.73-0.596,1.326-1.326,1.326
+ h-0.359c-0.732,0-1.325-0.596-1.325-1.326V34.326z M38.271,34.326c0-0.732,0.597-1.325,1.326-1.325h0.36
+ c0.729,0,1.325,0.597,1.325,1.325v0.361c0,0.73-0.597,1.326-1.325,1.326h-0.36c-0.729,0-1.326-0.596-1.326-1.326V34.326z
+ M23.213,54.09c-5.819,0-10.54-4.721-10.54-10.545c0-5.822,4.721-10.544,10.54-10.544c5.82,0,10.541,4.72,10.541,10.544
+ S29.033,54.09,23.213,54.09z M53.329,52.764c0,0.73-0.597,1.325-1.326,1.325H39.598c-0.729,0-1.326-0.597-1.326-1.325v-0.362
+ c0-0.729,0.597-1.325,1.326-1.325h12.405c0.729,0,1.326,0.597,1.326,1.325V52.764z M53.329,46.738
+ c0,0.729-0.597,1.325-1.326,1.325H39.598c-0.729,0-1.326-0.597-1.326-1.325v-0.361c0-0.729,0.597-1.325,1.326-1.325h12.405
+ c0.729,0,1.326,0.597,1.326,1.325V46.738z M53.329,40.711c0,0.732-0.597,1.326-1.326,1.326H39.598
+ c-0.729,0-1.326-0.595-1.326-1.326v-0.36c0-0.729,0.597-1.325,1.326-1.325h12.405c0.729,0,1.326,0.596,1.326,1.325V40.711z
+ M53.329,34.688c0,0.73-0.597,1.326-1.326,1.326h-0.358c-0.73,0-1.326-0.596-1.326-1.326v-0.361
+ c0-0.732,0.596-1.325,1.326-1.325h0.358c0.729,0,1.326,0.597,1.326,1.325V34.688z"/>
+ </g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M12.492,23.967h6.384c0.729,0,1.324-0.596,1.324-1.325v-1.873c0-0.731-0.595-1.326-1.324-1.326
+ H17.19v-4.776c0.256-0.092-0.449,0.346,0.754-0.349c1.202-0.692,2.9-4.012,1.652-6.173c-1.246-2.161-4.01-2.901-6.171-1.654
+ c-2.162,1.248-2.903,4.013-1.656,6.173c0.563,0.972,1.431,1.656,2.409,2.002v4.777h-1.686c-0.731,0-1.325,0.595-1.325,1.326
+ v1.873C11.167,23.372,11.762,23.967,12.492,23.967z"/>
+ <path style="fill:#FFFFFF;" d="M24.538,23.966h1.865c0.731,0,1.327-0.596,1.327-1.325v-0.368c0-0.73,0.594-1.325,1.325-1.325
+ h19.937c0.73,0,1.325,0.595,1.325,1.325v0.368c0,0.729,0.596,1.325,1.326,1.325h1.865c0.729,0,1.325-0.596,1.325-1.325v-0.909
+ c0-2.921-2.38-5.302-5.3-5.304c-7.324,0-13.696,0-21.022,0c-2.92,0-5.3,2.383-5.3,5.304v0.909
+ C23.213,23.371,23.81,23.966,24.538,23.966z"/>
+ <circle style="fill:#FFFFFF;" cx="23.213" cy="43.543" r="4.495"/>
+ <path style="fill:#FFFFFF;" d="M52.725,26.973h-39.45v0.001c-3.649,0-6.626,2.978-6.626,6.629v19.885
+ c0,3.65,2.979,6.628,6.626,6.628h39.45c3.649,0,6.627-2.978,6.627-6.628V33.601C59.352,29.952,56.374,26.973,52.725,26.973z
+ M44.296,34.326c0-0.732,0.593-1.325,1.325-1.325h0.359c0.73,0,1.326,0.597,1.326,1.325v0.361c0,0.73-0.596,1.326-1.326,1.326
+ h-0.359c-0.732,0-1.325-0.596-1.325-1.326V34.326z M38.271,34.326c0-0.732,0.597-1.325,1.326-1.325h0.36
+ c0.729,0,1.325,0.597,1.325,1.325v0.361c0,0.73-0.597,1.326-1.325,1.326h-0.36c-0.729,0-1.326-0.596-1.326-1.326V34.326z
+ M23.213,54.09c-5.819,0-10.54-4.721-10.54-10.545c0-5.822,4.721-10.544,10.54-10.544c5.82,0,10.541,4.72,10.541,10.544
+ S29.033,54.09,23.213,54.09z M53.329,52.764c0,0.73-0.597,1.325-1.326,1.325H39.598c-0.729,0-1.326-0.597-1.326-1.325v-0.362
+ c0-0.729,0.597-1.325,1.326-1.325h12.405c0.729,0,1.326,0.597,1.326,1.325V52.764z M53.329,46.738
+ c0,0.729-0.597,1.325-1.326,1.325H39.598c-0.729,0-1.326-0.597-1.326-1.325v-0.361c0-0.729,0.597-1.325,1.326-1.325h12.405
+ c0.729,0,1.326,0.597,1.326,1.325V46.738z M53.329,40.711c0,0.732-0.597,1.326-1.326,1.326H39.598
+ c-0.729,0-1.326-0.595-1.326-1.326v-0.36c0-0.729,0.597-1.325,1.326-1.325h12.405c0.729,0,1.326,0.596,1.326,1.325V40.711z
+ M53.329,34.688c0,0.73-0.597,1.326-1.326,1.326h-0.358c-0.73,0-1.326-0.596-1.326-1.326v-0.361
+ c0-0.732,0.596-1.325,1.326-1.325h0.358c0.729,0,1.326,0.597,1.326,1.325V34.688z"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/googlemaps_app_icon.png b/doc/images/googlemaps_app_icon.png
new file mode 100755
index 0000000..3cb3e8d
--- /dev/null
+++ b/doc/images/googlemaps_app_icon.png
Binary files differ
diff --git a/doc/images/googlemaps_app_icon.svg b/doc/images/googlemaps_app_icon.svg
new file mode 100755
index 0000000..425ca66
--- /dev/null
+++ b/doc/images/googlemaps_app_icon.svg
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 55.2 78.24" style="enable-background:new 0 0 55.2 78.24;" xml:space="preserve">
+<g id="Google_Maps_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="57" height="79" xlink:href="data:image/png;base64,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
+rkJggg==" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M31.942,51.883l-1.188,2.441c6.396,0.812,10.263,2.856,10.263,4.371
+ c0,1.931-6.239,4.733-16.017,4.733c-9.778,0-16.015-2.803-16.015-4.733c0-1.791,5.389-4.327,13.99-4.683l2.021,4.086
+ l13.887-28.053h-0.016c1.368-2.364,2.164-5.094,2.164-8.016C41.031,13.178,33.854,6,25.004,6
+ C16.151,6,8.972,13.178,8.972,22.03c0,2.921,0.796,5.654,2.16,8.016h-0.013L21.732,51.5C13.68,52.02,6.41,54.469,6.41,58.695
+ C6.41,63.493,15.761,66,25,66c9.24,0,18.59-2.507,18.59-7.305C43.592,55.126,38.408,52.827,31.942,51.883z M18.268,20.055
+ c0-3.721,3.015-6.736,6.734-6.736c3.725,0,6.734,3.015,6.734,6.736c0,3.717-3.01,6.732-6.734,6.732
+ C21.283,26.787,18.268,23.772,18.268,20.055z"/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M31.942,51.883l-1.188,2.441c6.396,0.812,10.263,2.856,10.263,4.371
+ c0,1.931-6.239,4.733-16.017,4.733c-9.778,0-16.015-2.803-16.015-4.733c0-1.791,5.389-4.327,13.99-4.683l2.021,4.086
+ l13.887-28.053h-0.016c1.368-2.364,2.164-5.094,2.164-8.016C41.031,13.178,33.854,6,25.004,6
+ C16.151,6,8.972,13.178,8.972,22.03c0,2.921,0.796,5.654,2.16,8.016h-0.013L21.732,51.5C13.68,52.02,6.41,54.469,6.41,58.695
+ C6.41,63.493,15.761,66,25,66c9.24,0,18.59-2.507,18.59-7.305C43.592,55.126,38.408,52.827,31.942,51.883z M18.268,20.055
+ c0-3.721,3.015-6.736,6.734-6.736c3.725,0,6.734,3.015,6.734,6.736c0,3.717-3.01,6.732-6.734,6.732
+ C21.283,26.787,18.268,23.772,18.268,20.055z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/homescreen_icon.png b/doc/images/homescreen_icon.png
new file mode 100755
index 0000000..d736310
--- /dev/null
+++ b/doc/images/homescreen_icon.png
Binary files differ
diff --git a/doc/images/hvac_app_icon.png b/doc/images/hvac_app_icon.png
new file mode 100755
index 0000000..27df1a0
--- /dev/null
+++ b/doc/images/hvac_app_icon.png
Binary files differ
diff --git a/doc/images/hvac_app_icon.svg b/doc/images/hvac_app_icon.svg
new file mode 100755
index 0000000..6626041
--- /dev/null
+++ b/doc/images/hvac_app_icon.svg
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="HVAC_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE8AAABPCAYAAACqNJiGAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
+GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAADZZJREFUeNrsnIly20gSRLtxELwk
+y57x7P9/3u7MWLIl8cSxZET1+ildDZKSZStmzYgO0jRFAIk6srKqGcKvx6/Hz3jEN3gO6d+DvD+8
+NfCqnwiW9xwdsAYBbvh/BE9BKjKvCVJva8DzmwGw+kGgRQEqrVKeCwGus9Xi9ZuxwOoHWRrBKu24
+x1XjdQkL7A2w/WHtsIIB+I+2PLW0EmBNbDV4PQGAgwF0BGtzWCuxyOEM940/wjqrVwTOA216WDOs
+qa3GPpPAOwK3PqxH+/sIN05x8JLMHV4j6VSvDFxtwBwBmh/WwtbS1tzW1D5bGEBHi3s4rDv7vs5c
+eG/uXADAOJKxg2Ox3w3E17K8BFwC7QjU1WFdH9Y7W1f2/gLgBQNoZcAVBtbG1tb+v5fjMQmNZW3N
+3i8CsfrOoNFVGwPuCNjNYb0/rA/2fGMALmF5lV3EEaB7+57WgHyQuNg7x0vPhYCnWbsV9++fC2D1
+Ci5b2oXODJwjUL/b+nhYvxmACbyZfT654tqssLWYN5eYWOFCNQlNJGsP4vI7ee4EyOFngMdYVwG8
+KwPqCNq/bCXwrsXqol3QxC7o0b6jAaWpERsLHGeGzyYAkzW1yNxprc3CtwAxXArga7ntBC773gD7
+w9bvZo1LA26CLLu15ymAqIQXTux4tcTTBay0kkSzRfZ+sOdHO+4GHPIiAL93wlDLW5p7JgB/s7h3
+nbnQYBdSSxxT4Er7/pSAbuz1Uiy5h9Udwfpi67PE0MIAvgjA13TbBpZxjXWFi6xBgKO5WJmpSCaw
+1AlCQrohN4ihtYC3Nov7bFl8hhtXZLLuSQCrZ4B0ym0VwBn43NyJTQWoQ+HUwuSLKcvOAdxHhIIr
+3JQE3h7gXUuSKp3MfG4VcxZ4MVOvDuKu0QFQM2Guls2RXVrdHH9/DeD+sNfJ8hoHvK257VLCBcu+
+zqEwL7K8mFmemRcZ5YTuV2asa8hIVsnqZriwqQGVgPvoxNES35uy7RxuXzlUZidVzEkJrDozjuny
+yp7CIaghU9Cfm7lJttN7CwPrI3jjjcTR0gGHCcLLxGupYrpT1lddUNxXMPXCKXsCLCvgfY+IjsWU
+KG4/NcCS2y8lc6dYNwNAhcSx0rHGLWJhysLJMjcjhnAWeHSbifCuEtpaCzMvnLveiju0AmIcydrJ
+6tKNagyoD06V0ohlBfn+QZKYp+7UAnR04vsoeLlqYS7BNkB3S/FicMBN/7+15wRg7dxdL9bt8H1T
+EO93ZpEecPGE1ucJtGPiQrgUPCojS3C0uQGa4sYW8aK175g4cWWDkmgKackDr4aFJIsr7O+SOrMQ
+V1WLUyl/j5vI0mwvYsGzy7Oc21wjvlzbRZSQi1a2NgBlAuK7FVmJVUQhx2asayFLlYh/S4foRkeC
+6pBtt3aO94hxXyzmrTOJYniO5ZGYLsxFUoa7sfcqCJesGTcI0un7W7G+nX13JxmctfEUYSB9XyMi
+QCUKCq2NSspaksPtYf11WH/b6884dwJ4NknO8aulgPebuU6NYv7R7ui93d2tHbyGhNTCXVKMrCVO
+FRIuogHZA9QmQ0k0QbEH8gjgjuXZJwPuL1t3du7JAtvnkGTPdRaijny0fzei/D7YCTzYv3dQP5hg
+vDhTiNVXcPt0EXy/lhjXO3FNQUvA3dr6ZOvW3k/uu3sJeOo6c1jfDZTgKWLaRgCkC0Rh9QziHVyX
+GbKQzwdkxdrhk51wtxU8IYkBdwCK6wtCzhY39SSxP+W2iaYsoJtdgZSWoCNs7jzCBTr7XqrBmhF7
+gKfBWs8rOsmhFc3uFGifDbR7nOvOAS481/IqiTFKLOfSZ+X7C9CXPdyuETWDAT4AiFaCdiHnR6to
+RS2mByTtzgNrm6ljXyTD53qunkJS46JrAZuZtcfxGvQsApSPHiDwotgXmdhFUgf0ksTGqVVbuRm8
+vhw96c8RBuKJ2pYsvJT3owR0CpcEIiAZeTFwL/2FHZJJLdbfi+zUOTW0R7talGwELyeTjQJ4jqoS
+RvS2KBxN72gjLsjqpRAOmHgYg3cHd0/xtJMMrPFRy8p03ES91lgrycqPjkCaBbByCuhcozinisSR
+mrEeGZEgL9uASqQMuAJ4qcrZ4VxZxWg52UmYWEhZthFyz/jo9X6Hcy2PwLWiiqhY2DtqMIXRHk3q
+Qb6fvCxRi09GWm/tolo7x6VULtogKhEPg3TwdnLuO1QdK2TmW2lIDRlVeciBp8Dt5U4xCezEZWMm
+8QxOwR5hkcny7s3qUtl0jyokWWEF7jnDe6XI/6mMY+buMpn5XoTU6IgKPTzFtbxByhwCt5J+5xR/
+O3H417mPXtRcllBfAF4HIZQl1CCEWrNn54SdVuLsvTO10IrU1oKv/s/6cpbXSuPkATFhBorSomdQ
+CB/T50LKqV7UD5ZWKeumE59ITdw5GVWnSgdnqVdtoB4XuJkbkebdki0HXheezsh9hn5WoabdwApz
+zR1PdByrJOLI5FMu48dM6BhGPKtF1VOgx0vZaurMv2TdVpsmGzSLG5GY1uHreNjE6Y4VUo/WouH1
+zpQB+7wd3Fb7vfVInPWevWZU50wWPKK3y7nBSm7icMryCB5r0haxguDVQqi9Eq+RvmoEH0x0ZG3H
+nwC8JRo9c6d9qDysyFhocKhZctW5rKkzkhHPpSoJvFJKoS1ceR6ejsVWMs1E8XIhRLlC9ZAmqnaw
+iCWoygKKzhLhg8PfuQHywlGrQ6YEbcLTWek6w/uyMU/1sbXcoZQVF+g86XA2R2l3kJ2oxykf65A9
+Z7DAEuC+M+tk0uqQeb3avJSWaXGiBM016DU8DGOW51UDezBztuzoklRWKJ8zW0WnPmbzZwHQS7j1
+AtaeSrM9ANQ4WosFlSdoVcyUpRePW5AUDk4zZQ3gKEcNKJ08sDSRaF08MZD2+C4Ohk9EmW6FxvRO
+EmocELVxPza77O6Dq0aACzhBFS8HASYB0TtKhlrnRNSM4GToBsctJI5yno83lN27QdRwesnESYCt
+NOW92eXhUstjJRCdu6J91jl6Ht5M3szJYkGaOAH1cMiMe+i4Bgn9BsBzIp9ZdIrv6kQ08Hq6bivy
+3BEzb4ognVQK5O/Q33iPrv4NwNPh7CIjNJL0MoOrAl2cALBAQkqSFqcM0k1il23lVBauWFpdCFoD
+2nEtTSGuG2RGPeGJY0E609I5g0NRGkVatQSIDA+iwkylD7OQjL0x6nUPqX51amLqnPk8tTbOGX/A
+tBKHb67Dt0PWjdP5GiTob6AgR5xfGb7d8aPuzNGxpNJs0TifSRNrgfbpzj5/CxBXThP82eA1cNP3
+mI/j3gp1Uc4QV8KztGW4ko5bgYvj/ovotCInUrb14etmmC3UH07PL+G6e7O2v01T5ATBLjzdaXnS
+bWMY31txE55uD+DeCrpoLYFedT1tGaq7tSjhSH280d2pNJe4h22H+McW6RTt05WB9reJAo/I3i+y
+PM2oVxLvdBq9cYYhPeBIupOSsUGDp4cA2jkKjFKimUhMnKVphXDPkHWTpT6gVfkYnu51u7gBFITE
+VlKzcicjT6jO1JWDE+dWOOkvZoVpI0saK/MuIGbEh6mIDy30uR4hqIHbDiKEsBHePYeq5LSwkCnA
+vSFBb37Z6/CzOb1B4J9kAnYM/sR8I+5biva4w3XX4eke307EWG9iKlzitrlZt53I1HuHkRfImqrW
+eLL7rb3eooqYj5HUkQmHxpGt9uB/0aE5Opq2P3Hsk+WZJ8uvZaRMNTbSkEL4HEspzsqlaaV7yO51
+OD2Vnhs810QVpDcxOOqzGsrJ3ZDnWl7nWIvOA0fUwjOpQz1Ji3NyiSI82jFn6H51I8ANGXbg/dzI
+IOrLEPIbm4dwxnToqZg3yB1LF66T8VE+t5X+QEBMSZTgCNafttKAIUf49ycmlnIxuT+jCdQ58dv7
+EZwX7QDSVuTaSQ7aQlyFb/d3BaENd2Zt/7HFPm0ivG2GnLL3q/FY41Xr9F6HjGaZuzEvAo9lUbKc
+wplSSsX1O8zv6bYDNrd1rHVlx5s7UwljFtQ6Lcu1NOi9TTRng/Rc8DwlOUoca5025VXw92zwVyuY
+KFIVUKJc6jL93U66fFqh3GNgaBWe7v/ow+VbuV4E3iBAjcXDe9HuFLytw+seQGDVZXVMYo9yqnfa
+o7dCezyy+90el1ieB6CXTL44omdACUQW/4DJAPKxvTNBsAlfty9QxGQCSmHgU3g64X72kPZrgOcB
+qDUqN4mo3B0d6WktEhRdVudkHiEM1FI1PKCgP2buf2PSKgfeT/lFHwKok0Rp8qjOqCne5hIKn1X4
+ditAsuTGjreGNMVQcQfL+9OAvBPL7r4ncM8Bz6MMWoXk+p65n3WjRreXEHAXvs7drUVC2omowL0V
+HJA8e//sjwDP6671cM0Y/N2D3rSSNqrZh2jgolsDgxsCd3Bp/moF91VsxOrCz0gYlygvueZxCPmf
+soyOTMVprIfw9Pem9CfiOD/IBs7+NWLd9wLPAyU6wOSY+5DhjCtp6FDgZEWjv9SzCf4c3/AWLe+c
+0mY48/OcC1QhwfsZkc6hNbqb/NWAey3wXgJ651Q0OuI1hPHfFH3xr5Od+4hvCLzcVKj3qxmqnuSU
+lFc/4fDGAFQgL/k1xh/6U8BvDTzvvOIF2f7X44Rb/3r8Ex7/FWAAbmuDLbSNFe0AAAAASUVORK5C
+YII=" transform="matrix(1 0 0 1 0.5 -0.76)">
+ </image>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M63.767,50.996c3.637-6.108,4.753-11.601,0.466-17.058c-4.386-2.455-10.646-2.62-16.574-1.51
+ c-0.228-0.682-0.52-1.337-0.869-1.955l16.978-9.657c-3.634-6.213-7.976-9.951-14.993-9.061
+ c-4.346,2.471-7.599,7.653-9.581,13.217c-0.711-0.142-1.44-0.219-2.192-0.219h-0.004L37.002,6
+ c-7.273,0-12.728,1.813-15.456,8.154c0,4.882,2.944,10.187,6.86,14.6c-0.458,0.542-0.867,1.13-1.217,1.754l-16.957-9.504
+ c-3.639,6.11-4.751,11.601-0.46,17.057c4.377,2.464,10.639,2.63,16.569,1.52c0.227,0.682,0.518,1.333,0.867,1.949l-16.977,9.654
+ c3.635,6.214,7.974,9.951,14.993,9.062c4.341-2.466,7.593-7.649,9.574-13.212c0.709,0.142,1.445,0.218,2.197,0.218L37.002,66
+ c7.269,0,12.722-1.813,15.449-8.151c0-4.876-2.945-10.179-6.86-14.593c0.456-0.543,0.864-1.129,1.216-1.754L63.767,50.996z
+ M42.625,36.003c0,3.105-2.521,5.625-5.625,5.625c-3.106,0-5.625-2.52-5.625-5.625c0-3.106,2.519-5.625,5.625-5.625
+ C40.104,30.377,42.625,32.897,42.625,36.003z"/>
+ </g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M63.767,50.996c3.637-6.108,4.753-11.601,0.466-17.058c-4.386-2.455-10.646-2.62-16.574-1.51
+ c-0.228-0.682-0.52-1.337-0.869-1.955l16.978-9.657c-3.634-6.213-7.976-9.951-14.993-9.061
+ c-4.346,2.471-7.599,7.653-9.581,13.217c-0.711-0.142-1.44-0.219-2.192-0.219h-0.004L37.002,6
+ c-7.273,0-12.728,1.813-15.456,8.154c0,4.882,2.944,10.187,6.86,14.6c-0.458,0.542-0.867,1.13-1.217,1.754l-16.957-9.504
+ c-3.639,6.11-4.751,11.601-0.46,17.057c4.377,2.464,10.639,2.63,16.569,1.52c0.227,0.682,0.518,1.333,0.867,1.949l-16.977,9.654
+ c3.635,6.214,7.974,9.951,14.993,9.062c4.341-2.466,7.593-7.649,9.574-13.212c0.709,0.142,1.445,0.218,2.197,0.218L37.002,66
+ c7.269,0,12.722-1.813,15.449-8.151c0-4.876-2.945-10.179-6.86-14.593c0.456-0.543,0.864-1.129,1.216-1.754L63.767,50.996z
+ M42.625,36.003c0,3.105-2.521,5.625-5.625,5.625c-3.106,0-5.625-2.52-5.625-5.625c0-3.106,2.519-5.625,5.625-5.625
+ C40.104,30.377,42.625,32.897,42.625,36.003z"/>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/icon_apps_blue.png b/doc/images/icon_apps_blue.png
new file mode 100755
index 0000000..95b534b
--- /dev/null
+++ b/doc/images/icon_apps_blue.png
Binary files differ
diff --git a/doc/images/icongear.png b/doc/images/icongear.png
new file mode 100755
index 0000000..fa619aa
--- /dev/null
+++ b/doc/images/icongear.png
Binary files differ
diff --git a/doc/images/media_player_app_icon.png b/doc/images/media_player_app_icon.png
new file mode 100755
index 0000000..2495afd
--- /dev/null
+++ b/doc/images/media_player_app_icon.png
Binary files differ
diff --git a/doc/images/media_player_app_icon.svg b/doc/images/media_player_app_icon.svg
new file mode 100755
index 0000000..1bae4ed
--- /dev/null
+++ b/doc/images/media_player_app_icon.svg
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="Media_Player_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAE8AAABPCAYAAACqNJiGAAAACXBIWXMAAAsSAAALEgHS3X78AAAA
+GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAC/1JREFUeNrsXIty2soS3JUWA8bO
+SfL/n3jvtWMbm4eQbqjaqdNuenYlwE7OqVA1xcNYSK159sxuCH8eZz/iP+Tchj/g1X9fvWfgau//
+teBF8ToWXjNAQ+H1p4OZPhm0SNI4r6MAD6V3Xn8qiPGTAWuEtM7nDF4v5OB8PhQ087fWPAYNQTJJ
+znMLYCrwDiCd83wgUD9MG9MHAIegISAzRxI8J9JEe6CmdVn28KyEgby6FsYPAq0BMI7A3GSZg9hn
+MwFeC8cz8zsI8I6yy7IFsc/28P2+4B9/meZ5oBk4iwzWMr9ewGesgWy2kQIDAohadgRsA/IGnxmQ
+DOLFWhiv8L/o0xA0A+s2yxJkDlrXOkGjFjAMyD1o3hvIaxYDE0E8XAPEdAUzbck8EbBVFnu/AOAS
++bZYSZbtt/BiDYAOANwAcOssN/l9S+YcLvGF6UIzRW1bZK06gnQHwsAl8GkD+SLPJ6nc0FxEBH+6
+zACilrOLeMsA2/EO52pguhC4GZw0gnafn03r7OQbAK0Ds+so1UAAWctbCkac/tg5oW/FAIURfUsR
+fRKA6QLg7G6beR4B+5LFgFvk75mm9eDsdySYYvQCvIZSnhsS9p8JgJyTu+CgtDsHwHM0D+/uKgN1
+BOyvLPf58zmYVU+O3aIiphcMXg+/2wjwEJSF8KeoiQhwEom4qpevBp4yVTPTryAIXJtPZE+OHCPi
+BvKyPUXCwfl9DE5z8LVLcB/o5+YAJifiHsHQjwExTTTXBGnIXda0I2jf8msDrskgWPpgUe+FACwB
+N1SC1IwCBfpdi/JLALGlBDwIcqGfUhOnM4BbgI8z8P7KJ23AdVmrjoA9g6wBvK0opfrCXVd1spnw
+K6RIGzi2BZ9FPv8FAdc7vz2M8X9pgp9LYK734OMsQNiJdRmcI1hPP+UHgPdKF9c5Jz5UcssIOVsC
+t8AlWgcALgHAIIgGVQsXNa8doXVmIqhxZqpfM3gL0Lg3AO3hpzzm1y8OeH0BwKHA5alqo3P8ZiSz
+RZ/XF9iYs8FrhJ9D4L5l4Jb5OAcA7jED95Dfv4CpdiKXU1WFOvGhQI4qE+wp3WlFtB0EYzOKiWlH
+RFcDbpXB+gZ+7jZrZZ816tkBzgr0g8jdVC075VHTygGUgRPqSNrHyXox6tbAM627Ba0zsQARska9
+CODWWePMeXPETE7SGs8kLkqRE6+pFWUigqdorFHgRUqGl5AIKz+3z77sB4CHprqHyNUSt7eg5JWJ
+gikgDo42BuH3kqN9SHUhgJPAa+FCbykt+SLMFf0cBgczVQRuAW4ASQMG0NPCOEELgyjzWmKvWwEe
+554yeLSFQDGD3AnLL0xLdhmoHxBVLSXZAu0T6XhGHtwD8+LVnuFCMy5VKUnU3TuH+zsBsK2UYWiy
+Vn7d5h/l6PoIfm5L5oq+EysTTLCRfeFeRgz1BnkJwEhBIxGD3QDTsxeVTz9G87xAgcnwPH9vL7QO
+IyumCQmIBAs837NgabccAeAUbYyOL0/UAsCcDwmMnWB63AqDyzGmfhIQiFi3csl1EKxIC6Z7BwDe
+5c8PkO6YNq/y62dgh7l6OBTKKczh9nDOxjKbv23hJt8IFoZ7Km55psBDMtPUm3sGW6Hmiq6fQ8Jt
+Wmc+1FKep/z3RwgsT/l/X4mN6SAN6h1qvSeTxPO+pbbAjHosyctD00jmgn3DHhorb3QhTGR6NTIC
+uMp/w7r4nhjpFQSkdaVOHhwN7ESzaAPa1zjXrTp6RbNtRWswipPYOpGp1DBC+t4C0jz/3xZAYzEA
+nwDEN8GkqPIKE2F17j3V8jOgsmTQShUWhQ8Sqd3n0ec1UlVRXEsgF1ZA79+J1OauAOLOYaTZ//E1
+9MQ+z0Q6M8psVT7UiFKG+bhBpAc1Xg5BnAH/ht04BvEBAF5CpE/ZnKNoL/LkwV4kwuzvvYg/ymxb
+h7buz+DAovCBqlkeaTQDK5IVmfCKmugt/Y6alhoK5865YHuO2TYO/6VY2HPnP6Jjytb7SKInvBQT
+CHNyK4PoBysAe4f3q137CXil4UNFGymSMpwJnHIXQbAvM9LIG5Hg8gwLpjGhcO6DuJEqOcfzHlIl
+G69Na4Zwvamj2o1TWoAVAY5ZWNIuk9tCkycWrh+/M5TM1tOOMILtDVcCMYj2YE8VwLwyEVAjWWu9
+kmIZ2FzhQj/qoaj2Q0UmtQ4vPf80UZtiRS4FS9HqnTBN6wE/5+cXUV93lTamJ8NYLU0jmFhv6Kah
+52toWA/k6UHUo2tgco653v9+yn/y8yNxifvC9IE6/zgioARFDAwU5tUwYShEpGai9g3iuSeGhLXN
+NA3p/iNo/83PDwDgW6HWLp1/gEBUna5PhSaKauU1Irl1M3BHw4KTb3WCtUETRdL1geQH9E1eqenE
+eZx3/pGAq04xJOcCvT5mCO/njlOFNh9rpnvSFNS2J9C2R9AwZK8RtI1gWTzgUJpCG1JWT8kBrg+n
+I/t2gIbKqZnTSK6BdyDTtMcuA/EsQDMtU6TA1iEFSjT8DXF5HKS8SfpitD042frNCMa1KSTNgyAm
+bVZ4C32RZwgKDzS2UWJSvGkEnoDwGPKhUKWMMts+6AlOuwPMhMyp78AUfBCuwLRtnf+3o77Ik/Bp
+U4nQodBamFPfGNsLXThdx9HXehjDCNLwQD3dBbEadjEN8Wjs3zYZpGX+zkv+zkZEVA4GG4eA9Vgd
+NSaH60JuoJ4+FEjeYarZ4hisAWPFOE/A4yCPWvOFwK0zIG1+n4iC/wHyAto2pfmjph9wqQOCh+2F
+rXODJpvtDnoVdkBc8mQs8Gvwp6Awgu0AIAMMW5lvYLZsop4Zleb5FOGKa0SMgI0EHPrSUWZbcurW
+rrNWnYV3A8+7Ux1pnkXSlD97A/Z4T23BkonWmJzSRKux0Su4FmxqjS7zkpP5s396g4MuQftsUnRX
+6LD3AKRpXsjfXTsms6mkHmPqb9S4ZXi/3OEeJhQitVI5XxyV5wXHRzFXhoM5s/z+4ORFAZorffh7
+vYNpYStSBF5oV/NrNeB4hhrBm0EpiNfIjaRhCqsyOH5vDc52Dj1YpLTVVFEHN2QL4EVoZ/Ii5KkU
+v+rM8azN1/B+aj9Svrl2/N3oKalaj4HbctwgKjETnAp1VJoVM/oRoDXUVMe5wu/h/YhcKyK8lXuv
+YLaT5vNK4HFPAXu6XqPEa770hS7cFBP1lnTZNNY3ENO6BHnlCwH3AqzMoXQD2wlMq+osMTmg2nRx
+BEM8hHGbKjAX15J/Q+BQ4xC4WT7WNujZwnUGtQtnziR74IXgb7jAAF46GhYrTaGWyi3L4XBi/zv5
+uRmQD0xzecPnZ4NXalozt9cEvUtFK1jbJvgT8U2le8atyAUkvV/IVM3Hscatw/t1Io9krlWtK6Uq
+Ku+zXEjth4KgGkmwCqcbNVhB7hX2Y9eeeVp3F94vXbWJgiSAewzvhzJVeXkReJz32Qyd6l2gzzKm
+4lY48yXVqttwumC5tN5W3Qxckn8Pcyw2OmY5JgKn+h5dKa87BzzWPq9th+sfVsBWLKgwNyLhVVQS
+akSMNW4WTpeM3pIsgMDoALgnMtUnCBC7KVo3VfO4bCsRCl14v2A5hb+XWWG5hFt3qH1QeHJJEZlq
+OXwLgWELwKnI+lYrwy4FDwE8jOx77EkLIlyYXfSetI7NFwObyi95UxueIdwQpY/c4Fr0Oz5kpbcH
+4OAwxVbyeHsNzAjEA/UNkKuLIkiotCjA/yFTbS1LprmQ4J0M3DngMYA18Kwm5qXrbSFnq/k8BmwA
+s+Ml+WuYKMAOm2KAPmVfFRVEuNfLF8HzdDfU8ovhdMwrEHhRUFzoY3lQ+1Vwg5swYmXPR4MXBF83
+FLpjuEEM7kJxE05H9UsjHlEQtrtwumsGTrp7m0BcPBp3jSknb08pbE/yNh4MngIwUM9VAafAU7uZ
+deGKe0hdEzxVBahKQG0mw7RWaVwjViitnRO5Jy9//xXgeTRW47AwM1EL14aF1EA2d/cVYL/15oM1
+EKOoiZk8wEARR/jYQzgdyGEN+xDQPho8BWJptq/GAQaHUPWWxX/4ZqufAV4JyBDO21PAGyT/FMB+
+FXg1knXMOZV25x5+5UX8Do+pGzH8efxTH/8XYACFYNx2lyiIBQAAAABJRU5ErkJggg==" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M8.61,35.999c0-15.105,12.288-27.39,27.39-27.39c15.103,0,27.392,12.285,27.392,27.39
+ c0,15.104-12.289,27.39-27.392,27.39C20.898,63.389,8.61,51.103,8.61,35.999z M36,66c16.543,0,29.998-13.461,29.998-30.001
+ C65.998,19.458,52.543,6,36,6S6.002,19.458,6.002,35.999C6.002,52.539,19.457,66,36,66z"/>
+ </g>
+ <g>
+ <polygon style="fill:#FFFFFF;" points="49.043,35.999 37.956,42.398 26.867,48.803 26.868,35.999 26.868,23.195
+ 37.956,29.599 "/>
+ </g>
+ </g>
+ </g>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M8.61,35.999c0-15.105,12.288-27.39,27.39-27.39c15.103,0,27.392,12.285,27.392,27.39
+ c0,15.104-12.289,27.39-27.392,27.39C20.898,63.389,8.61,51.103,8.61,35.999z M36,66c16.543,0,29.998-13.461,29.998-30.001
+ C65.998,19.458,52.543,6,36,6S6.002,19.458,6.002,35.999C6.002,52.539,19.457,66,36,66z"/>
+ </g>
+ <g>
+ <polygon style="fill:#FFFFFF;" points="49.043,35.999 37.956,42.398 26.867,48.803 26.868,35.999 26.868,23.195
+ 37.956,29.599 "/>
+ </g>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/news_app_icon.png b/doc/images/news_app_icon.png
new file mode 100755
index 0000000..33752f4
--- /dev/null
+++ b/doc/images/news_app_icon.png
Binary files differ
diff --git a/doc/images/news_app_icon.svg b/doc/images/news_app_icon.svg
new file mode 100755
index 0000000..e30ffe2
--- /dev/null
+++ b/doc/images/news_app_icon.svg
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 75.36 64.32" style="enable-background:new 0 0 75.36 64.32;" xml:space="preserve">
+<g id="News_Icon">
+ <g id="news_1_">
+
+ <image style="overflow:visible;opacity:0.5;" width="75" height="65" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 0.5 -0.68)">
+ </image>
+ <g>
+ <path style="fill:#FFFFFF;" d="M13.625,20.097H49.25v-3.563H13.625V20.097z M33.218,41.468h12.468v-3.561H33.218V41.468z
+ M33.218,34.344H49.25V30.78H33.218V34.344z M33.218,27.222H49.25v-3.564H33.218V27.222z M13.625,41.468h16.031v-17.81H13.625
+ V41.468z M56.375,12.971V5.845H6.5v39.186c0,0,0,7.124,7.125,7.124h44.532c0,0,5.343-0.11,5.343-7.124v-32.06H56.375z
+ M13.625,48.596c-3.564,0-3.564-3.564-3.564-3.564V9.408h42.752v35.623c0,1.643,0.506,2.776,1.202,3.564H13.625z"/>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/nfc_app_icon.png b/doc/images/nfc_app_icon.png
new file mode 100755
index 0000000..43c3a87
--- /dev/null
+++ b/doc/images/nfc_app_icon.png
Binary files differ
diff --git a/doc/images/nfc_app_icon.svg b/doc/images/nfc_app_icon.svg
new file mode 100755
index 0000000..a104c0f
--- /dev/null
+++ b/doc/images/nfc_app_icon.svg
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 69.6" style="enable-background:new 0 0 78.24 69.6;" xml:space="preserve">
+<g id="NFC_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="71" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 0.5 -1.4)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M62.626,7.539c-0.705-1.833-2.619-2.71-4.154-1.998c-1.531,0.714-2.18,2.586-1.552,4.217
+ c5.278,13.664,5.278,28.823,0,42.485c-0.628,1.632,0.019,3.503,1.552,4.217c1.535,0.714,3.449-0.165,4.154-1.998
+ C68.458,39.368,68.458,22.63,62.626,7.539z"/>
+ <path style="fill:#FFFFFF;" d="M46.469,12.375c-1.53,0.72-2.175,2.593-1.582,4.226c3.561,9.746,3.561,19.037,0,28.783
+ c-0.593,1.634,0.052,3.506,1.582,4.225c1.53,0.719,3.47-0.204,4.165-2.113c4.059-11.106,4.059-21.898,0-33.006
+ C49.938,12.581,47.999,11.658,46.469,12.375z"/>
+ <path style="fill:#FFFFFF;" d="M34.51,17.5c-1.531,0.729-2.165,2.602-1.64,4.24c1.523,4.68,1.843,9.932,0.961,14.733
+ L13.844,21.396c-0.464-0.367-1-0.576-1.548-0.636c-1.401-0.237-2.969,0.759-3.548,2.535c-2.331,7.162-2.331,9.976,0,17.14
+ c0.667,2.053,2.659,3.065,4.182,2.335c1.529-0.728,2.167-2.601,1.64-4.239c-1.46-4.486-1.815-6.209-1.064-9.596l20.061,15.14
+ c0.507,0.399,1.099,0.609,1.695,0.648c1.369,0.162,2.872-0.829,3.429-2.554c2.33-7.162,2.33-15.17,0-22.333
+ C38.026,17.784,36.032,16.771,34.51,17.5z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M62.626,7.539c-0.705-1.833-2.619-2.71-4.154-1.998c-1.531,0.714-2.18,2.586-1.552,4.217
+ c5.278,13.664,5.278,28.823,0,42.485c-0.628,1.632,0.019,3.503,1.552,4.217c1.535,0.714,3.449-0.165,4.154-1.998
+ C68.458,39.368,68.458,22.63,62.626,7.539z"/>
+ <path style="fill:#FFFFFF;" d="M46.469,12.375c-1.53,0.72-2.175,2.593-1.582,4.226c3.561,9.746,3.561,19.037,0,28.783
+ c-0.593,1.634,0.052,3.506,1.582,4.225c1.53,0.719,3.47-0.204,4.165-2.113c4.059-11.106,4.059-21.898,0-33.006
+ C49.938,12.581,47.999,11.658,46.469,12.375z"/>
+ <path style="fill:#FFFFFF;" d="M34.51,17.5c-1.531,0.729-2.165,2.602-1.64,4.24c1.523,4.68,1.843,9.932,0.961,14.733
+ L13.844,21.396c-0.464-0.367-1-0.576-1.548-0.636c-1.401-0.237-2.969,0.759-3.548,2.535c-2.331,7.162-2.331,9.976,0,17.14
+ c0.667,2.053,2.659,3.065,4.182,2.335c1.529-0.728,2.167-2.601,1.64-4.239c-1.46-4.486-1.815-6.209-1.064-9.596l20.061,15.14
+ c0.507,0.399,1.099,0.609,1.695,0.648c1.369,0.162,2.872-0.829,3.429-2.554c2.33-7.162,2.33-15.17,0-22.333
+ C38.026,17.784,36.032,16.771,34.51,17.5z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/phone_app_icon.png b/doc/images/phone_app_icon.png
new file mode 100755
index 0000000..3e3c9ac
--- /dev/null
+++ b/doc/images/phone_app_icon.png
Binary files differ
diff --git a/doc/images/phone_app_icon.svg b/doc/images/phone_app_icon.svg
new file mode 100755
index 0000000..606dde9
--- /dev/null
+++ b/doc/images/phone_app_icon.svg
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 74.4" style="enable-background:new 0 0 78.24 74.4;" xml:space="preserve">
+<g id="Phone_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="75" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 0.5 -0.6)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M7.276,22.697c-0.316,0.817-0.354,1.583-0.146,2.278c-0.217,1.8-1.238,15.551,16.188,28.336
+ c17.688,12.981,30.171,8.167,31.923,6.938c0.713-0.019,1.418-0.286,2.091-0.822c1.34-1.073,3.564-3.578,4.377-4.938
+ c1.153-1.918,0.583-3.096-1.205-3.985l-12.772-6.396c-1.279-0.637-2.803-0.146-3.422,1.04l-2.447,4.706
+ c-0.146,0.282-0.214,0.594-0.217,0.906c-0.373,0.288-3.991,2.76-12.199-3.465c-8.431-6.395-9.651-9.922-9.137-12.253
+ c0.276-0.096,0.53-0.25,0.74-0.46l3.752-3.748c0.947-0.946,0.959-2.546-0.031-3.577l-9.934-10.265
+ c-1.387-1.438-2.68-1.631-4.163,0.046C9.618,18.226,7.9,21.099,7.276,22.697z"/>
+ <path style="fill:#FFFFFF;" d="M29.384,17.6l1.581,2.58c0,0,0.442,0.653,0.716,0.796c0.437,0.228,0.91,0.216,1.399,0.226
+ c3.904,0.071,7.727,1.322,10.943,3.685c3.565,2.617,6.053,6.28,7.165,10.432c0.12,0.443,0.146,0.706,0.592,1.191
+ c0.217,0.238,0.741,0.438,0.741,0.438l3.105,0.861c0,0,0.477,0.086,0.791-0.11c0.316-0.197,0.538-0.547,0.459-1.068
+ c-0.965-6.403-4.395-12.125-9.71-16.025c-4.953-3.636-11.02-5.241-17.046-4.601c0,0-0.715,0.047-0.893,0.761
+ C29.093,17.295,29.384,17.6,29.384,17.6z"/>
+ <path style="fill:#FFFFFF;" d="M62.088,39.265c0.317,0.417,0.893,0.53,0.893,0.53l2.952,0.836c0,0,0.322,0.062,0.576-0.057
+ C66.807,40.434,67,39.949,67,39.453C67,20.93,51.902,5.859,33.379,5.859c-2.939,0-5.863,0.394-8.679,1.147
+ c-0.51,0.136-0.833,0.439-0.932,0.838c-0.079,0.319,0.096,0.727,0.096,0.727l1.494,2.451c0,0,0.398,0.587,0.701,0.707
+ c0.49,0.197,1.004,0.147,1.529,0.04c1.92-0.394,3.92-0.597,5.87-0.597c15.201,0,27.74,12.052,28.366,27.103
+ C61.823,38.274,61.771,38.851,62.088,39.265z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M7.276,22.697c-0.316,0.817-0.354,1.583-0.146,2.278c-0.217,1.8-1.238,15.551,16.188,28.336
+ c17.688,12.981,30.171,8.167,31.923,6.938c0.713-0.019,1.418-0.286,2.091-0.822c1.34-1.073,3.564-3.578,4.377-4.938
+ c1.153-1.918,0.583-3.096-1.205-3.985l-12.772-6.396c-1.279-0.637-2.803-0.146-3.422,1.04l-2.447,4.706
+ c-0.146,0.282-0.214,0.594-0.217,0.906c-0.373,0.288-3.991,2.76-12.199-3.465c-8.431-6.395-9.651-9.922-9.137-12.253
+ c0.276-0.096,0.53-0.25,0.74-0.46l3.752-3.748c0.947-0.946,0.959-2.546-0.031-3.577l-9.934-10.265
+ c-1.387-1.438-2.68-1.631-4.163,0.046C9.618,18.226,7.9,21.099,7.276,22.697z"/>
+ <path style="fill:#FFFFFF;" d="M29.384,17.6l1.581,2.58c0,0,0.442,0.653,0.716,0.796c0.437,0.228,0.91,0.216,1.399,0.226
+ c3.904,0.071,7.727,1.322,10.943,3.685c3.565,2.617,6.053,6.28,7.165,10.432c0.12,0.443,0.146,0.706,0.592,1.191
+ c0.217,0.238,0.741,0.438,0.741,0.438l3.105,0.861c0,0,0.477,0.086,0.791-0.11c0.316-0.197,0.538-0.547,0.459-1.068
+ c-0.965-6.403-4.395-12.125-9.71-16.025c-4.953-3.636-11.02-5.241-17.046-4.601c0,0-0.715,0.047-0.893,0.761
+ C29.093,17.295,29.384,17.6,29.384,17.6z"/>
+ <path style="fill:#FFFFFF;" d="M62.088,39.265c0.317,0.417,0.893,0.53,0.893,0.53l2.952,0.836c0,0,0.322,0.062,0.576-0.057
+ C66.807,40.434,67,39.949,67,39.453C67,20.93,51.902,5.859,33.379,5.859c-2.939,0-5.863,0.394-8.679,1.147
+ c-0.51,0.136-0.833,0.439-0.932,0.838c-0.079,0.319,0.096,0.727,0.096,0.727l1.494,2.451c0,0,0.398,0.587,0.701,0.707
+ c0.49,0.197,1.004,0.147,1.529,0.04c1.92-0.394,3.92-0.597,5.87-0.597c15.201,0,27.74,12.052,28.366,27.103
+ C61.823,38.274,61.771,38.851,62.088,39.265z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/settings_icon.png b/doc/images/settings_icon.png
new file mode 100755
index 0000000..44fb3d8
--- /dev/null
+++ b/doc/images/settings_icon.png
Binary files differ
diff --git a/doc/images/shift_off_icon.png b/doc/images/shift_off_icon.png
new file mode 100755
index 0000000..720a69a
--- /dev/null
+++ b/doc/images/shift_off_icon.png
Binary files differ
diff --git a/doc/images/shift_on_icon.png b/doc/images/shift_on_icon.png
new file mode 100755
index 0000000..503ff24
--- /dev/null
+++ b/doc/images/shift_on_icon.png
Binary files differ
diff --git a/doc/images/space_bar_icon.png b/doc/images/space_bar_icon.png
new file mode 100755
index 0000000..2b5c2fa
--- /dev/null
+++ b/doc/images/space_bar_icon.png
Binary files differ
diff --git a/doc/images/switchcontrol.png b/doc/images/switchcontrol.png
new file mode 100755
index 0000000..1c350b5
--- /dev/null
+++ b/doc/images/switchcontrol.png
Binary files differ
diff --git a/doc/images/switchplate_off.png b/doc/images/switchplate_off.png
new file mode 100755
index 0000000..16250c5
--- /dev/null
+++ b/doc/images/switchplate_off.png
Binary files differ
diff --git a/doc/images/switchplate_on.png b/doc/images/switchplate_on.png
new file mode 100755
index 0000000..43bb554
--- /dev/null
+++ b/doc/images/switchplate_on.png
Binary files differ
diff --git a/doc/images/symbols_icon.png b/doc/images/symbols_icon.png
new file mode 100755
index 0000000..07e1deb
--- /dev/null
+++ b/doc/images/symbols_icon.png
Binary files differ
diff --git a/doc/images/symbols_off_icon.png b/doc/images/symbols_off_icon.png
new file mode 100755
index 0000000..59cd170
--- /dev/null
+++ b/doc/images/symbols_off_icon.png
Binary files differ
diff --git a/doc/images/tizen.png b/doc/images/tizen.png
new file mode 100755
index 0000000..c6674d6
--- /dev/null
+++ b/doc/images/tizen.png
Binary files differ
diff --git a/doc/images/weather_app_icon.png b/doc/images/weather_app_icon.png
new file mode 100755
index 0000000..dcb46ee
--- /dev/null
+++ b/doc/images/weather_app_icon.png
Binary files differ
diff --git a/doc/images/weather_app_icon.svg b/doc/images/weather_app_icon.svg
new file mode 100755
index 0000000..d1fb79c
--- /dev/null
+++ b/doc/images/weather_app_icon.svg
@@ -0,0 +1,115 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!-- Generator: Adobe Illustrator 18.1.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
+ viewBox="0 0 78.24 78.24" style="enable-background:new 0 0 78.24 78.24;" xml:space="preserve">
+<g id="Weather_Icon">
+ <g>
+
+ <image style="overflow:visible;opacity:0.5;" width="79" height="79" xlink:href="data:image/png;base64,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" transform="matrix(1 0 0 1 -0.5 -0.76)">
+ </image>
+ <g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M51.748,36.001c0,8.65-7.016,15.662-15.664,15.662c-8.653,0-15.665-7.012-15.665-15.662
+ c0-8.649,7.012-15.665,15.665-15.665C44.732,20.336,51.748,27.352,51.748,36.001z"/>
+ <path style="fill:#FFFFFF;" d="M39.317,13.745c0,1.831-1.484,3.313-3.317,3.313c-1.83,0-3.313-1.482-3.313-3.313
+ c0-1.83,1.484-7.744,3.313-7.744C37.833,6.001,39.317,11.915,39.317,13.745z"/>
+ <path style="fill:#FFFFFF;" d="M32.687,58.256c0-1.829,1.484-3.313,3.313-3.313c1.833,0,3.317,1.484,3.317,3.313
+ c0,1.83-1.484,7.743-3.317,7.743C34.17,65.999,32.687,60.086,32.687,58.256z"/>
+ <path style="fill:#FFFFFF;" d="M54.081,22.608c-1.296,1.294-3.391,1.294-4.686,0c-1.299-1.295-1.299-3.395,0-4.689
+ c1.295-1.295,6.523-4.426,7.818-3.131C58.508,16.083,55.376,21.313,54.081,22.608z"/>
+ <path style="fill:#FFFFFF;" d="M17.919,49.395c1.298-1.293,3.394-1.293,4.689,0c1.296,1.297,1.296,3.39,0,4.687
+ c-1.294,1.296-6.523,4.429-7.819,3.133C13.493,55.92,16.625,50.691,17.919,49.395z"/>
+ <path style="fill:#FFFFFF;" d="M58.257,39.316c-1.831,0-3.317-1.485-3.317-3.316c0-1.83,1.486-3.313,3.317-3.313
+ C60.086,32.688,66,34.17,66,36C66,37.831,60.086,39.316,58.257,39.316z"/>
+ <path style="fill:#FFFFFF;" d="M13.744,32.688c1.832,0,3.318,1.483,3.318,3.313c0,1.831-1.486,3.316-3.318,3.316
+ C11.916,39.316,6,37.831,6,36C6,34.17,11.916,32.688,13.744,32.688z"/>
+ <path style="fill:#FFFFFF;" d="M49.396,54.081c-1.299-1.297-1.299-3.39,0-4.687c1.295-1.293,3.39-1.293,4.686,0
+ c1.295,1.297,4.427,6.525,3.133,7.819C55.919,58.51,50.69,55.377,49.396,54.081z"/>
+ <path style="fill:#FFFFFF;" d="M22.607,17.919c1.296,1.294,1.296,3.394,0,4.689c-1.294,1.294-3.391,1.294-4.689,0
+ c-1.294-1.295-4.425-6.525-3.13-7.82C16.084,13.493,21.313,16.624,22.607,17.919z"/>
+ </g>
+ </g>
+ <g>
+ <g>
+ <path style="fill:#FFFFFF;" d="M51.748,36.001c0,8.65-7.016,15.662-15.664,15.662c-8.653,0-15.665-7.012-15.665-15.662
+ c0-8.649,7.012-15.665,15.665-15.665C44.732,20.336,51.748,27.352,51.748,36.001z"/>
+ <path style="fill:#FFFFFF;" d="M39.317,13.745c0,1.831-1.484,3.313-3.317,3.313c-1.83,0-3.313-1.482-3.313-3.313
+ c0-1.83,1.484-7.744,3.313-7.744C37.833,6.001,39.317,11.915,39.317,13.745z"/>
+ <path style="fill:#FFFFFF;" d="M32.687,58.256c0-1.829,1.484-3.313,3.313-3.313c1.833,0,3.317,1.484,3.317,3.313
+ c0,1.83-1.484,7.743-3.317,7.743C34.17,65.999,32.687,60.086,32.687,58.256z"/>
+ <path style="fill:#FFFFFF;" d="M54.081,22.608c-1.296,1.294-3.391,1.294-4.686,0c-1.299-1.295-1.299-3.395,0-4.689
+ c1.295-1.295,6.523-4.426,7.818-3.131C58.508,16.083,55.376,21.313,54.081,22.608z"/>
+ <path style="fill:#FFFFFF;" d="M17.919,49.395c1.298-1.293,3.394-1.293,4.689,0c1.296,1.297,1.296,3.39,0,4.687
+ c-1.294,1.296-6.523,4.429-7.819,3.133C13.493,55.92,16.625,50.691,17.919,49.395z"/>
+ <path style="fill:#FFFFFF;" d="M58.257,39.316c-1.831,0-3.317-1.485-3.317-3.316c0-1.83,1.486-3.313,3.317-3.313
+ C60.086,32.688,66,34.17,66,36C66,37.831,60.086,39.316,58.257,39.316z"/>
+ <path style="fill:#FFFFFF;" d="M13.744,32.688c1.832,0,3.318,1.483,3.318,3.313c0,1.831-1.486,3.316-3.318,3.316
+ C11.916,39.316,6,37.831,6,36C6,34.17,11.916,32.688,13.744,32.688z"/>
+ <path style="fill:#FFFFFF;" d="M49.396,54.081c-1.299-1.297-1.299-3.39,0-4.687c1.295-1.293,3.39-1.293,4.686,0
+ c1.295,1.297,4.427,6.525,3.133,7.819C55.919,58.51,50.69,55.377,49.396,54.081z"/>
+ <path style="fill:#FFFFFF;" d="M22.607,17.919c1.296,1.294,1.296,3.394,0,4.689c-1.294,1.294-3.391,1.294-4.689,0
+ c-1.294-1.295-4.425-6.525-3.13-7.82C16.084,13.493,21.313,16.624,22.607,17.919z"/>
+ </g>
+ </g>
+ </g>
+ </g>
+</g>
+<g id="Layer_1">
+</g>
+</svg>
diff --git a/doc/images/white_return.png b/doc/images/white_return.png
new file mode 100755
index 0000000..0385846
--- /dev/null
+++ b/doc/images/white_return.png
Binary files differ
diff --git a/export.map b/export.map
new file mode 100755
index 0000000..0ef1ac7
--- /dev/null
+++ b/export.map
@@ -0,0 +1 @@
+{ global: afbBindingV1Register; local: *; };
diff --git a/icon_wifi_128.png b/icon_wifi_128.png
new file mode 100755
index 0000000..4651b61
--- /dev/null
+++ b/icon_wifi_128.png
Binary files differ
diff --git a/imports/components/AwesomeIcon.qml b/imports/components/AwesomeIcon.qml
new file mode 100755
index 0000000..542fb0f
--- /dev/null
+++ b/imports/components/AwesomeIcon.qml
@@ -0,0 +1,26 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import system 1.0
+import components 1.0
+import utils 1.0
+
+Item {
+ height: icon.height
+ width: icon.height
+
+ property alias iconSize: icon.font.pixelSize
+ property alias ucKey: icon.text
+ property alias iconColor: icon.color
+
+ Text {
+ id: icon
+ font.family: "FontAwesome"
+ color: "white"
+ }
+}
+
diff --git a/imports/components/Box.qml b/imports/components/Box.qml
new file mode 100755
index 0000000..a2f2ae0
--- /dev/null
+++ b/imports/components/Box.qml
@@ -0,0 +1,49 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ id: root
+
+ opacity: 0.8
+ property color color: Style.grey
+ property color border: color
+ property string shadow: ""
+
+ OutShadow {
+ color: root.color
+ visible: root.shadow === "out"
+ }
+
+ Rectangle {
+ id: rect
+ anchors.fill: parent
+ color: Style.black
+ border.width: 1
+ border.color: root.border
+ }
+
+ InsetShadow {
+ color: root.color
+ visible: root.shadow === "fill"
+ }
+
+ InShadow {
+ color: root.color
+ visible: root.shadow === "in"
+ }
+
+ Rectangle {
+ visible: root.shadow === "fill"
+ anchors.fill: parent
+ color: "transparent"
+ border.width: 1
+ border.color: root.border
+ }
+
+}
diff --git a/imports/components/BoxButton.qml b/imports/components/BoxButton.qml
new file mode 100755
index 0000000..0969f46
--- /dev/null
+++ b/imports/components/BoxButton.qml
@@ -0,0 +1,36 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import components 1.0
+
+Item {
+ id: root
+
+ property alias shadow: box.shadow
+ property alias color: box.color
+ property alias text: textItem.text
+
+ signal clicked()
+
+ Box {
+ id: box
+ anchors.fill: parent
+
+ Text {
+ id: textItem
+ anchors.centerIn: parent
+ horizontalAlignment: Text.AlignHCenter
+ font.pixelSize: 28
+ color: "white"
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.clicked()
+ }
+ }
+}
diff --git a/imports/components/BoxHeading.qml b/imports/components/BoxHeading.qml
new file mode 100755
index 0000000..bb2c62a
--- /dev/null
+++ b/imports/components/BoxHeading.qml
@@ -0,0 +1,37 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Row {
+ id: root
+
+ property color color: Style.blueViv
+ property alias fontSize: headingText.font.pixelSize
+ property alias text: headingText.text
+ property alias boxWidth: box.width
+ property alias boxHeight: box.height
+
+ spacing: 10
+
+ Rectangle {
+ id: box
+ anchors.bottom: headingText.baseline
+ anchors.bottomMargin: 0
+ width: 100
+ height: 16
+ color: root.color
+ }
+
+ Text {
+ id: headingText
+ font.family: "Source Sans Pro"
+ font.pixelSize: 22
+ font.weight: Font.Bold
+ color: root.color
+ }
+}
diff --git a/imports/components/Button.qml b/imports/components/Button.qml
new file mode 100755
index 0000000..9d5c495
--- /dev/null
+++ b/imports/components/Button.qml
@@ -0,0 +1,30 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Rectangle {
+ id: root
+ border.color: "#cccccc"
+ color:"#222"
+ border.width: 2
+ height: pairText.height + 20
+ width: pairText.width + 20
+
+ property string buttonText
+
+
+ Text {
+ id: pairText
+ anchors.centerIn: parent
+ font.family: "Source Sans Pro"
+ font.pixelSize: 48
+ font.weight: Font.Bold
+ color: "white"
+ font.capitalization: Font.AllUppercase
+ text: buttonText
+ }
+}
diff --git a/imports/components/DateTime.qml b/imports/components/DateTime.qml
new file mode 100755
index 0000000..6203712
--- /dev/null
+++ b/imports/components/DateTime.qml
@@ -0,0 +1,35 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ id: dateTime
+ anchors.left: parent.left
+ anchors.right: parent.right
+ height: 120
+ property var timeStamp: new Date()
+
+ Timer {
+ interval: 1000
+ running: true
+ repeat: true
+ onTriggered: timeStamp = new Date()
+ }
+
+ Label {
+ fontColor: Style.grey
+ text: Qt.formatDate(timeStamp, "ddd MMM d")
+ }
+
+ Label {
+ anchors.right: parent.right
+ fontColor: Style.grey
+ text: Qt.formatTime(timeStamp, "h:mm AP")
+ }
+}
+
diff --git a/imports/components/HexGrid.qml b/imports/components/HexGrid.qml
new file mode 100755
index 0000000..b81a09a
--- /dev/null
+++ b/imports/components/HexGrid.qml
@@ -0,0 +1,32 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Item {
+ property real spacing: 0
+ property int columns: 3
+
+ width: childrenRect.width
+ height: childrenRect.height
+
+ Component.onCompleted: {
+ var sizeX = childrenRect.height
+ var sizeY = childrenRect.width
+ var column = 0
+ var row = 0
+
+ for (var n = 0; n < children.length; n++) {
+ children[n].x = column * (sizeX + spacing)
+ children[n].y = row * (0.5 * sizeY + spacing)
+ column += 2
+ if (column >= columns) {
+ row++
+ column = row % 2
+ }
+ }
+ }
+}
diff --git a/imports/components/HexSwitch.qml b/imports/components/HexSwitch.qml
new file mode 100755
index 0000000..cce82b3
--- /dev/null
+++ b/imports/components/HexSwitch.qml
@@ -0,0 +1,80 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+Item {
+ width: 170 * height / 80
+ height: 80
+
+ property bool value
+ property bool showLabels: false
+
+ Image {
+ anchors.fill: parent
+ source: "../../doc/images/switchplate_" + (value ? "on" : "off") + ".png"
+ }
+
+ Item {
+ id: shadowTarget
+ x: value ? parent.width * 0.375 : -11
+ width: parent.width * 0.7
+ height: parent.height
+
+ Image {
+ id: control
+ anchors.centerIn: parent
+ width: parent.height * 0.9
+ fillMode: Image.PreserveAspectFit
+ source: "../../doc/images/switchcontrol.png"
+ }
+ }
+
+ DropShadow {
+ anchors.fill: shadowTarget
+ cached: true
+ horizontalOffset: parent.height * 0.05
+ verticalOffset: parent.height * 0.05
+ radius: 16
+ samples: 32
+ color: Qt.rgba(0, 0, 0, 0.35)
+ smooth: true
+ source: shadowTarget
+ }
+
+ Text {
+ text: qsTr("OFF")
+ font.family: "Source Sans Pro"
+ anchors.right: parent.left
+ anchors.rightMargin: 30
+ anchors.verticalCenter: parent.verticalCenter
+ font.pointSize: 25
+ font.letterSpacing: -0.5
+ font.weight: value ? Font.Normal : Font.Bold
+ color: value ? "#C4C4C4" : "#FE9C00"
+ visible: showLabels
+ }
+
+ Text {
+ id: onText
+ text: qsTr("ON")
+ font.family: "Source Sans Pro"
+ anchors.left: parent.right
+ anchors.leftMargin: 30
+ font.pointSize: 25
+ anchors.verticalCenter: parent.verticalCenter
+ font.letterSpacing: -0.5
+ font.weight: value ? Font.Bold : Font.Normal
+ color: value ? "#59FF00" : "#C4C4C4"
+ visible: showLabels
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: value = !value
+ }
+}
diff --git a/imports/components/InShadow.qml b/imports/components/InShadow.qml
new file mode 100755
index 0000000..2d64c2a
--- /dev/null
+++ b/imports/components/InShadow.qml
@@ -0,0 +1,33 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+ShaderEffect {
+ anchors.fill: parent
+ property color color
+ property real radius: 16
+
+ fragmentShader: "
+uniform lowp float radius;
+uniform lowp float height;
+uniform lowp float width;
+uniform lowp float qt_Opacity;
+uniform lowp vec4 color;
+varying highp vec2 qt_TexCoord0;
+
+void main(void) {
+ lowp vec2 dist = min(qt_TexCoord0, vec2(1.0) - qt_TexCoord0);
+ // Border shadow
+ lowp float xval = smoothstep(0.0, radius, dist.x * width);
+ lowp float yval = smoothstep(0.0, radius, dist.y * height);
+ lowp float borderVal = sqrt(yval * xval) * 0.5 + 0.5;
+
+ lowp vec4 borderColor = mix(color, vec4(0.0, 0.0, 0.0, 1.0), borderVal);
+ gl_FragColor = borderColor * qt_Opacity;
+}
+ "
+}
diff --git a/imports/components/InsetShadow.qml b/imports/components/InsetShadow.qml
new file mode 100755
index 0000000..6ad17cd
--- /dev/null
+++ b/imports/components/InsetShadow.qml
@@ -0,0 +1,40 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+ShaderEffect {
+ anchors.fill: parent
+ property color color
+ property real radius: 100
+ property real border: 20
+
+ fragmentShader: "
+uniform lowp float radius;
+uniform lowp float border;
+uniform lowp float height;
+uniform lowp float width;
+uniform lowp float qt_Opacity;
+uniform lowp vec4 color;
+varying highp vec2 qt_TexCoord0;
+
+void main(void) {
+ lowp vec2 dist = min(qt_TexCoord0, vec2(1.0) - qt_TexCoord0);
+ // Border shadow
+ lowp float xval = smoothstep(0.0, border, dist.x * width);
+ lowp float yval = smoothstep(0.0, border, dist.y * height);
+ lowp float borderVal = sqrt(yval * xval) * 0.5 + 0.5;
+ // Inner shadow
+ xval = smoothstep(0.0, radius, dist.x * width);
+ yval = smoothstep(0.0, radius, dist.y * width);
+ lowp float innerVal = sqrt(yval * xval) * 0.5 + 0.5;
+
+ lowp vec4 innerColor = mix(vec4(0.0, 0.0, 0.0, 0.5), color, innerVal);
+ lowp vec4 borderColor = mix(vec4(0.0, 0.0, 0.0, 1.0), innerColor, borderVal);
+ gl_FragColor = borderColor * qt_Opacity;
+}
+ "
+}
diff --git a/imports/components/Label.qml b/imports/components/Label.qml
new file mode 100755
index 0000000..e1e0b30
--- /dev/null
+++ b/imports/components/Label.qml
@@ -0,0 +1,27 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ // Tracer {}
+ width: childrenRect.width
+ height: childrenRect.height
+ property alias text: text.text
+ property alias label: text
+ property alias fontSize: text.font.pixelSize
+ property alias fontColor: text.color
+
+ Text {
+ id: text
+ color: "#ddd"
+ font.family: "Source Sans Pro"
+ font.pixelSize: 40
+ font.capitalization: Font.AllUppercase
+ font.weight: Font.Bold
+ }
+}
diff --git a/imports/components/NumberPad.qml b/imports/components/NumberPad.qml
new file mode 100755
index 0000000..b7763ca
--- /dev/null
+++ b/imports/components/NumberPad.qml
@@ -0,0 +1,101 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ id: root
+ height: childrenRect.height
+ property var letters: ["","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"]
+ property var bottomRow: ["*","0","#"]
+
+ signal number(string number)
+
+ Grid {
+ id: numberGrid
+ columns: 3
+ spacing: 20
+
+ Repeater {
+ model: 9
+ delegate: Item {
+ id: numberKey
+ width: (root.width - ( numberGrid.spacing*(numberGrid.columns-1)))/numberGrid.columns
+ height: numberKey.width * 0.8
+ anchors.margins: 10
+
+ Rectangle {
+ id: shadowTarget
+ anchors.fill: parent
+ border.width: 1
+ border.color: "white"
+ color: "#6653b5ce"
+ }
+
+ Item {
+ height: childrenRect.height
+ width: parent.width
+ anchors.centerIn: parent
+
+ Label {
+ anchors.horizontalCenter: parent.horizontalCenter
+ id: keypadNumber
+ text: index + 1
+ }
+
+ Label {
+ anchors.horizontalCenter: parent.horizontalCenter
+ id: keypadLetters
+ anchors.top: keypadNumber.bottom
+ fontSize: 30
+ fontColor: "#53b5ce"
+ text: letters[index]
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.number(keypadNumber.text)
+ }
+ }
+ }
+
+ Repeater {
+ model: 3
+ delegate: Item {
+ width: (root.width - ( numberGrid.spacing*(numberGrid.columns-1)))/numberGrid.columns
+ height: width * 0.8
+ anchors.margins: 10
+
+ Rectangle {
+ id: shadowTarget
+ anchors.fill: parent
+ border.width: 1
+ border.color: "white"
+ color: "#6653b5ce"
+ }
+
+ Item {
+ height: childrenRect.height
+ width: parent.width
+ anchors.centerIn: parent
+
+ Label {
+ anchors.horizontalCenter: parent.horizontalCenter
+ id: keypadNumber
+ text: bottomRow[index]
+ }
+ }
+
+ MouseArea {
+ anchors.fill: parent
+ onClicked: root.number(keypadNumber.text)
+ }
+ }
+ }
+ }
+}
diff --git a/imports/components/OutShadow.qml b/imports/components/OutShadow.qml
new file mode 100755
index 0000000..f4d8407
--- /dev/null
+++ b/imports/components/OutShadow.qml
@@ -0,0 +1,41 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import QtGraphicalEffects 1.0
+
+Item {
+ id: root
+
+ anchors.fill: parent
+ property alias color: shadow.color
+ property alias radius: shadow.radius
+
+ Item {
+ id: shadowTarget
+ x: -radius
+ y: -radius
+ width: parent.width + 2 * radius
+ height: parent.height + 2 * radius
+
+ Rectangle {
+ anchors.centerIn: parent
+ width: root.width
+ height: root.height
+ color: "black"
+ }
+ }
+
+ DropShadow {
+ id: shadow
+ anchors.fill: shadowTarget
+ horizontalOffset: 0
+ verticalOffset: 0
+ radius: 16
+ samples: 32
+ source: shadowTarget
+ }
+}
diff --git a/imports/components/Switch.qml b/imports/components/Switch.qml
new file mode 100755
index 0000000..6cd50c7
--- /dev/null
+++ b/imports/components/Switch.qml
@@ -0,0 +1,13 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+
+Switch {
+ width: 100
+ height: 62
+}
+
diff --git a/imports/components/qmldir b/imports/components/qmldir
new file mode 100755
index 0000000..57e4d2d
--- /dev/null
+++ b/imports/components/qmldir
@@ -0,0 +1,16 @@
+#/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+# *
+# * This Source Code Form is subject to the terms of the Mozilla Public
+# * License, v. 2.0. If a copy of the MPL was not distributed with this
+# * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+AwesomeIcon 1.0 AwesomeIcon.qml
+Box 1.0 Box.qml
+BoxButton 1.0 BoxButton.qml
+BoxHeading 1.0 BoxHeading.qml
+DateTime 1.0 DateTime.qml
+HexGrid 1.0 HexGrid.qml
+HexSwitch 1.0 HexSwitch.qml
+Label 1.0 Label.qml
+NumberPad 1.0 NumberPad.qml
+Button 1.0 Button.qml
diff --git a/imports/radio/Radio.qml b/imports/radio/Radio.qml
new file mode 100755
index 0000000..cea2e1a
--- /dev/null
+++ b/imports/radio/Radio.qml
@@ -0,0 +1,6 @@
+import QtQuick 2.0
+
+Item {
+ signal stopped
+ signal playing
+}
diff --git a/imports/radio/qmldir b/imports/radio/qmldir
new file mode 100755
index 0000000..e334188
--- /dev/null
+++ b/imports/radio/qmldir
@@ -0,0 +1,2 @@
+Radio 1.0 Radio.qml
+RadioPropertyItem 1.0 Radio.qml
diff --git a/imports/system/App.qml b/imports/system/App.qml
new file mode 100755
index 0000000..d7da73c
--- /dev/null
+++ b/imports/system/App.qml
@@ -0,0 +1,29 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import system 1.0
+
+FocusScope {
+ id: root
+ property string appId
+ anchors.fill: parent
+ visible: System.activeApp === appId
+ property bool hasKeyFocus: false
+ focus: visible
+ onFocusChanged: if (focus) hasKeyFocus = true
+
+ Keys.onPressed: {
+ switch (event.key) {
+ case Qt.Key_Left:
+ case Qt.Key_Right:
+ root.hasKeyFocus = false
+ break
+ default:
+ break
+ }
+ }
+}
diff --git a/imports/system/System.qml b/imports/system/System.qml
new file mode 100755
index 0000000..8e155fd
--- /dev/null
+++ b/imports/system/System.qml
@@ -0,0 +1,15 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+import QtQuick 2.0
+
+Item {
+ property string activeApp: "home"
+ property string activeSetting: "settings"
+ property bool showKeyboard: false
+ property bool showSettings: false
+}
diff --git a/imports/system/qmldir b/imports/system/qmldir
new file mode 100755
index 0000000..afa0f56
--- /dev/null
+++ b/imports/system/qmldir
@@ -0,0 +1,8 @@
+#/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+# *
+# * This Source Code Form is subject to the terms of the Mozilla Public
+# * License, v. 2.0. If a copy of the MPL was not distributed with this
+# * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+singleton System 1.0 System.qml
+App 1.0 App.qml
diff --git a/imports/utils/Marker.qml b/imports/utils/Marker.qml
new file mode 100755
index 0000000..c7a377e
--- /dev/null
+++ b/imports/utils/Marker.qml
@@ -0,0 +1,60 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+import QtQuick 2.0
+import utils 1.0
+
+Item {
+ id: root
+ width: 120
+ height: 120
+ property string text
+ signal clicked()
+ property alias pressed: area.pressed
+ property alias color: background.color
+ property alias fontSize: label.font.pixelSize
+ property bool fill: false
+
+ Rectangle {
+ id: background
+ anchors.fill: parent
+ color: Style.backgroundColor
+ opacity: root.fill ? 1.0: 0.2
+ }
+
+ Rectangle {
+ id: frame
+ anchors.fill: parent
+ color: 'transparent'
+ border.color: Qt.darker(background.color, 1.4)
+ border.width: 2
+ opacity: 1.0
+ }
+
+
+ Rectangle {
+ anchors.fill: label
+ anchors.margins: -2
+ color: Style.backgroundColor
+ opacity: root.text ? 1.0 : 0.0
+ }
+
+ Text {
+ id: label
+ anchors.centerIn: parent
+ font.pixelSize: 14
+ color: Style.greyDarkColor
+ opacity: 0.75
+ text: root.text
+ }
+ MouseArea {
+ id: area
+ anchors.fill: parent
+ onClicked: root.clicked()
+ onPressed: background.color = Qt.darker(background.color, 1.5)
+ onReleased: background.color = Qt.lighter(background.color, 1.5)
+ }
+}
diff --git a/imports/utils/Style.qml b/imports/utils/Style.qml
new file mode 100755
index 0000000..ef544a6
--- /dev/null
+++ b/imports/utils/Style.qml
@@ -0,0 +1,37 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+import QtQuick 2.2
+
+QtObject {
+ property bool debugMode: false
+ property bool debugFill: false
+
+ // Primary colors
+ property color orangeLt: "#ffd38c"
+ property color orangeViv: "#fe9c00"
+ property color blueLt: "#b2f0ff"
+ property color blueViv: "#53b5ce"
+ // Secondary colors
+ property color yellowLt: "#ffffb2"
+ property color yellowViv: "#ffff00"
+ property color greenLt: "#cdffb2"
+ property color greenViv: "#59ff00"
+ // Neutral colors
+ property color white: "#ffffff"
+ property color grey: "#c4c4c4"
+ property color black: "#000000"
+ property color overlay: Qt.rgba(0, 0, 0, 0.8)
+
+ function getGfxPath() {
+ return Qt.resolvedUrl("../assets/")
+ }
+
+ function gfx(name) {
+ return Qt.resolvedUrl("../../doc/images/" + name )
+ }
+}
diff --git a/imports/utils/qmldir b/imports/utils/qmldir
new file mode 100755
index 0000000..c2df9de
--- /dev/null
+++ b/imports/utils/qmldir
@@ -0,0 +1,8 @@
+#/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+# *
+# * This Source Code Form is subject to the terms of the Mozilla Public
+# * License, v. 2.0. If a copy of the MPL was not distributed with this
+# * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+singleton Style 1.0 Style.qml
+Marker 1.0 Marker.qml
diff --git a/imports/vehicle/ClimateModel.qml b/imports/vehicle/ClimateModel.qml
new file mode 100755
index 0000000..9633f16
--- /dev/null
+++ b/imports/vehicle/ClimateModel.qml
@@ -0,0 +1,44 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+
+import QtQuick 2.0
+import Automotive.ClimateControl 1.0
+
+Item {
+ property real fanStepSize:1/255 //Represents the stepSize for a given Climate control.
+ property alias fanSpeed: fanControl.fanSpeedLevel
+
+ property real temperatureStepSize:1/15 //0== 15c, 15 == 30c
+
+ property alias leftTemp: leftFront.targetTemperature
+ property alias rightTemp: rightFront.targetTemperature
+
+ ClimateControlItem {
+ id:fanControl
+ }
+
+ ClimateControlItem {
+ id: leftFront
+ zone: 9
+ }
+
+ ClimateControlItem {
+ id: rightFront
+ zone: 5
+ }
+
+ function getRangeValue(inputVal,stepSize){
+ if(inputVal > 0){
+ return Math.ceil(inputVal/stepSize);
+ }else{
+ return 0;
+ }
+ }
+
+}
+
diff --git a/imports/vehicle/FuelModel.qml b/imports/vehicle/FuelModel.qml
new file mode 100755
index 0000000..fa064e2
--- /dev/null
+++ b/imports/vehicle/FuelModel.qml
@@ -0,0 +1,46 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+
+import QtQuick 2.0
+
+Item {
+ property bool metric: false
+
+ function galToL(value) {
+ return (metric ? 3.78541 : 1) * value
+ }
+
+ function mpgToLp100(value) {
+ return metric ? 235.214583571 / value : value
+ }
+
+ property real baseTank: 25
+ property real tankSize: galToL(baseTank)
+ property real level: tankSize * percentage * 0.01
+ property real percentage: 100
+ property real range: metric ? 100 * level / average : level * average
+ property real baseAverage: 20.7
+ property real average: mpgToLp100(baseAverage + mpgDiff)
+ property real mpgDiff: 0
+
+ NumberAnimation on percentage {
+ from: 100
+ to: 0
+ duration: 5000
+ loops: Animation.Infinite
+ easing.type: Easing.CosineCurve
+ }
+
+ NumberAnimation on mpgDiff {
+ from: -2
+ to: 2
+ duration: 11200
+ loops: Animation.Infinite
+ easing.type: Easing.CosineCurve
+ }
+}
diff --git a/imports/vehicle/PositionModel.qml b/imports/vehicle/PositionModel.qml
new file mode 100755
index 0000000..00956aa
--- /dev/null
+++ b/imports/vehicle/PositionModel.qml
@@ -0,0 +1,33 @@
+/* Copyright (C) 2015, Jaguar Land Rover, IoT.bzh. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+
+import QtQuick 2.0
+import amb 0.1
+
+Item {
+ property string nmeaString: nmea.value
+ property real satellites: satsUsed.value
+
+ AutomotivePropertyItem {
+ id: nmea
+
+ objectName: "GpsNmea"
+ propertyName: "Nmea"
+
+ Component.onCompleted: nmea.connect();
+ }
+
+ AutomotivePropertyItem {
+ id: satsUsed
+
+ objectName: "GpsSatsUsed"
+ propertyName: "SatsUsed"
+
+ Component.onCompleted: satsUsed.connect();
+ }
+}
diff --git a/imports/vehicle/SpeedModel.qml b/imports/vehicle/SpeedModel.qml
new file mode 100755
index 0000000..03422b0
--- /dev/null
+++ b/imports/vehicle/SpeedModel.qml
@@ -0,0 +1,38 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+
+import QtQuick 2.0
+import amb 0.1
+
+Item {
+ property bool metric: false
+
+ function mphToKph(value) {
+ return (metric ? 1.60934 : 1 ) * value
+ }
+
+ property real max:Math.ceil(mphToKph(baseMaxSpeed)/30)*30
+ property real baseMaxSpeed: 255
+ property real textSpeed: prop.value
+ property real percentage: textSpeed / max * 100
+
+ AutomotivePropertyItem {
+ id: prop
+
+ objectName: "VehicleSpeed"
+ propertyName: "Speed"
+
+ Component.onCompleted: prop.connect();
+ }
+
+ Behavior on percentage {
+ SmoothedAnimation {
+ velocity: 100
+ }
+ }
+}
diff --git a/imports/vehicle/TemperatureModel.qml b/imports/vehicle/TemperatureModel.qml
new file mode 100755
index 0000000..2bfbbf4
--- /dev/null
+++ b/imports/vehicle/TemperatureModel.qml
@@ -0,0 +1,26 @@
+/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+pragma Singleton
+
+import QtQuick 2.0
+
+Item {
+ property bool metric: true
+
+ function unit(value) {
+ return celsiusToFahrenheit(value).toFixed(1) + "\u00b0" + (metric ? "C" : "F")
+ }
+
+ function celsiusToFahrenheit(value) {
+ return (metric ? value : 1.8 * value + 32)
+ }
+
+ property real indoor: 20.4
+ property string indoorString: unit(indoor)
+ property real outdoor: 28.9
+ property string outdoorString: unit(outdoor)
+}
diff --git a/imports/vehicle/qmldir b/imports/vehicle/qmldir
new file mode 100755
index 0000000..6538e95
--- /dev/null
+++ b/imports/vehicle/qmldir
@@ -0,0 +1,11 @@
+#/* Copyright (C) 2015, Jaguar Land Rover. All Rights Reserved.
+# *
+# * This Source Code Form is subject to the terms of the Mozilla Public
+# * License, v. 2.0. If a copy of the MPL was not distributed with this
+# * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+singleton FuelModel 1.0 FuelModel.qml
+singleton SpeedModel 1.0 SpeedModel.qml
+singleton TemperatureModel 1.0 TemperatureModel.qml
+singleton PositionModel 1.0 PositionModel.qml
+singleton ClimateModel 1.0 ClimateModel.qml
diff --git a/oe-sdk_crosscompile.cmake b/oe-sdk_crosscompile.cmake
new file mode 100755
index 0000000..9669344
--- /dev/null
+++ b/oe-sdk_crosscompile.cmake
@@ -0,0 +1,20 @@
+# this toolchain file comes from gnuradio project
+# https://raw.githubusercontent.com/intel-iot-devkit/upm/master/cmake/Toolchains/oe-sdk_cross.cmake
+
+set( CMAKE_SYSTEM_NAME Linux )
+#set( CMAKE_C_COMPILER $ENV{CC} )
+#set( CMAKE_CXX_COMPILER $ENV{CXX} )
+string(REGEX MATCH "sysroots/([a-zA-Z0-9]+)" CMAKE_SYSTEM_PROCESSOR $ENV{SDKTARGETSYSROOT})
+string(REGEX REPLACE "sysroots/" "" CMAKE_SYSTEM_PROCESSOR ${CMAKE_SYSTEM_PROCESSOR})
+set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS} CACHE STRING "" FORCE )
+set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE ) #same flags for C sources
+set( CMAKE_LDFLAGS_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE ) #same flags for C sources
+set( CMAKE_LIBRARY_PATH ${OECORE_TARGET_SYSROOT}/usr/lib )
+set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} $ENV{OECORE_NATIVE_SYSROOT} )
+set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
+set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
+set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
+set( CMAKE_INSTALL_PREFIX $ENV{OECORE_TARGET_SYSROOT}/usr CACHE STRING "" FORCE)
+set( ORC_INCLUDE_DIRS $ENV{OECORE_TARGET_SYSROOT}/usr/include/orc-0.4 )
+set( ORC_LIBRARY_DIRS $ENV{OECORE_TARGET_SYSROOT}/usr/lib )
+
diff --git a/qml/wifi-settings/components/images/back.png b/qml/wifi-settings/components/images/back.png
new file mode 100755
index 0000000..5cbf54c
--- /dev/null
+++ b/qml/wifi-settings/components/images/back.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi1-lock.png b/qml/wifi-settings/components/images/wifi1-lock.png
new file mode 100755
index 0000000..e452041
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi1-lock.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi1.png b/qml/wifi-settings/components/images/wifi1.png
new file mode 100755
index 0000000..a680f54
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi1.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi2-lock.png b/qml/wifi-settings/components/images/wifi2-lock.png
new file mode 100755
index 0000000..3557341
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi2-lock.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi2.png b/qml/wifi-settings/components/images/wifi2.png
new file mode 100755
index 0000000..8299111
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi2.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi3-lock.png b/qml/wifi-settings/components/images/wifi3-lock.png
new file mode 100755
index 0000000..eefbc64
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi3-lock.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi3.png b/qml/wifi-settings/components/images/wifi3.png
new file mode 100755
index 0000000..35cb8a6
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi3.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi4-lock.png b/qml/wifi-settings/components/images/wifi4-lock.png
new file mode 100755
index 0000000..551ec76
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi4-lock.png
Binary files differ
diff --git a/qml/wifi-settings/components/images/wifi4.png b/qml/wifi-settings/components/images/wifi4.png
new file mode 100755
index 0000000..baced2e
--- /dev/null
+++ b/qml/wifi-settings/components/images/wifi4.png
Binary files differ
diff --git a/qml/wifi-settings/wifi-settings-app.qml b/qml/wifi-settings/wifi-settings-app.qml
new file mode 100755
index 0000000..c25934d
--- /dev/null
+++ b/qml/wifi-settings/wifi-settings-app.qml
@@ -0,0 +1,625 @@
+/* Copyright 2016 ALPS ELECTRIC 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.
+*/
+
+import QtQuick 2.0
+import QtQuick.Layouts 1.1
+import QtQuick.Dialogs 1.1
+import QtQuick.Controls 1.0
+import QtQuick.Controls.Styles 1.0
+import system 1.0
+
+import "../../doc/"
+import "../../imports/system/"
+
+ApplicationWindow {
+
+ visible: true
+ //width: 768
+ //height: 1024
+ width: 1080
+ height: 1920
+ property string protocol: 'http://'
+ property string ipAddress: '127.0.0.1'
+ property string portNumber: Qt.application.arguments[1]
+ property string tokenString: Qt.application.arguments[2]
+ property string wifiAPI: '/api/wifi-manager/'
+
+ property string wifiAPIpath: protocol + ipAddress + ':' + portNumber + wifiAPI
+
+ function showRequestInfo(text) {
+ log.text = log.text + "\n" + text
+ console.log(text)
+ }
+
+ Text {
+ id: log
+ anchors.fill: parent
+ anchors.margins: 10
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ //text: "log"
+ }
+
+ GridLayout {
+ ExclusiveGroup {
+ id: wifiPowerGroup
+ }
+ visible: true
+
+ id: seekDeviceType
+ //x: 400
+ //y: 105
+ anchors.top: parent.top
+ anchors.topMargin: 30
+
+ //anchors.bottomMargin: -30 //-20
+ anchors.horizontalCenter: parent.horizontalCenter
+ //visible: !tuningMethodManualSwitchButton.checked
+
+ //anchors.top: functionalityCheckBoxGrid.bottom
+ columns: 13
+ rows: 1
+
+ columnSpacing: 60
+
+ Text {
+ text: qsTr("WiFi power")
+ }
+
+ RadioButton {
+ id: wifiPowerOFF
+ exclusiveGroup: wifiPowerGroup
+ checked: true
+ onClicked: {
+
+ console.log("OFF")
+
+ request(wifiAPIpath + 'deactivate', function (o) {
+
+ // log the json response
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ }
+ Text {
+ text: qsTr("OFF")
+ anchors.left: parent.left
+ anchors.leftMargin: 30
+ }
+ }
+
+ RadioButton {
+ id: wifiPowerON
+ exclusiveGroup: wifiPowerGroup
+ onClicked: {
+
+ console.log("ON")
+
+ request(wifiAPIpath + 'activate', function (o) {
+
+ // log the json response
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ periodicRefresh.start()
+ }
+
+ Text {
+ text: qsTr("ON")
+ anchors.left: parent.left
+ anchors.leftMargin: 30
+ //color: checkBoxTextStyleBands.fontColor
+ //font.pixelSize: checkBoxTextStyleBands.fontSize
+ }
+ }
+ }
+
+
+ // onTechnologyEnabledChanged: {
+ // console.log("Wifi set to", technologyEnabled)
+
+ // if (technologyEnabled == true) {
+
+ // //start periodic refresh, only for now
+ // periodicRefresh.start()
+
+ // request(wifiAPIpath + 'activate', function (o) {
+
+ // // log the json response
+ // showRequestInfo(o.responseText)
+ // console.log(o.responseText)
+ // })
+ // } else {
+
+ // //console.log(networkPath)
+ // networkList.clear()
+
+ // request(wifiAPIpath + 'deactivate', function (o) {
+
+ // // log the json response
+ // showRequestInfo(o.responseText)
+ // console.log(o.responseText)
+ // })
+ // }
+ // }
+ Text {
+ anchors.centerIn: parent
+ font.pixelSize: 40
+ color: "white"
+ visible: false
+ text: "Wifi TB by ALCZ"
+ }
+
+ function listWifiNetworks() {
+ console.log("test #4")
+ }
+
+ ListModel {
+ id: networkList
+ }
+
+ Rectangle {
+ id: buttonNetworkList
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+
+ anchors.margins: 10
+ width: buttonNetworkListText.width + 10
+ height: buttonScanText.height + 10
+ border.width: buttonNetworkListMouseArea.pressed ? 2 : 1
+ radius: 5
+ antialiasing: true
+ color: "#222"
+ border.color: "white"
+
+ Text {
+ color: "white"
+ id: buttonNetworkListText
+ anchors.centerIn: parent
+ text: "GET NETWORK LIST"
+ font.pixelSize: 40
+ }
+
+ ListModel {
+ id: listModel
+ }
+
+ MouseArea {
+ id: buttonNetworkListMouseArea
+ anchors.fill: parent
+
+ onClicked: {
+ log.text = ""
+ console.log("\n")
+
+ networkList.clear()
+
+ request(wifiAPIpath + 'scan_result', function (o) {
+
+ // log the json response
+ console.log(o.responseText)
+
+ // translate response into object
+ var jsonObject = eval('(' + o.responseText + ')')
+
+ var jsonObjectNetworks = eval(
+ '(' + JSON.stringify(jsonObject.response) + ')')
+
+ //console.log(jsonObject.response)
+ for (var i = 0; i < jsonObjectNetworks.length; i++) {
+
+ networkList.append({
+ number: jsonObjectNetworks[i].Number,
+ name: jsonObjectNetworks[i].ESSID,
+ strength: jsonObjectNetworks[i].Strength,
+ serviceState: jsonObjectNetworks[i].State,
+ security: jsonObjectNetworks[i].Security,
+ address: jsonObjectNetworks[i].IPAddress
+ })
+ console.log(jsonObjectNetworks[i].Number,
+ jsonObjectNetworks[i].ESSID,
+ jsonObjectNetworks[i].Strength,
+ jsonObjectNetworks[i].State,
+ jsonObjectNetworks[i].Security,
+ jsonObjectNetworks[i].IPAddress)
+ }
+ })
+ }
+ }
+ }
+
+ Rectangle {
+ id: buttonScan
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.bottom: parent.bottom
+ anchors.margins: 80
+ width: buttonScanText.width + 10
+ height: buttonScanText.height + 10
+ border.width: mouseArea.pressed ? 2 : 1
+ //radius: 5
+ //antialiasing: true
+ //color: "black"
+ color: "#222"
+ border.color: "white"
+
+ Text {
+ id: buttonScanText
+ anchors.centerIn: parent
+ text: "SCAN"
+ color: "white"
+ font.pixelSize: 40
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+
+ onClicked: {
+ log.text = ""
+ console.log("\n")
+
+ request(wifiAPIpath + 'scan', function (o) {
+
+ // log the json response
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ }
+ }
+ }
+
+ function request(url, callback) {
+ var xhr = new XMLHttpRequest()
+ xhr.onreadystatechange = (function (myxhr) {
+
+ return function () {
+
+ if (xhr.readyState == 4 && xhr.status == 200)
+ callback(myxhr)
+ }
+ })(xhr)
+ xhr.open('GET', url, false)
+ xhr.send('')
+ }
+
+ /* function signalStrength(strength) {
+ if (strength < 30)
+ return "poor"
+ else if (strength >= 30 && strength < 50)
+ return "fair"
+ else if (strength >= 50 && strength < 70)
+ return "good"
+ else
+ return "excellent" }*/
+ function securityType(security) {
+
+ // if ((security === "[ psk ]") || (security === "[ psk wps ]"))
+ // return "secured"
+ // else
+ // return "unsecured"
+ if (security === "Open")
+ return "unsecured"
+ else
+ return "secured"
+ }
+
+ Component {
+ id: wifiDevice
+
+ Rectangle {
+ height: 150
+ width: parent.width
+ color: "#222"
+
+ Image {
+ anchors.top: parent.top
+ anchors.topMargin: 7
+ anchors.left: parent.left
+ width: 70
+ height: 50
+ id: icon
+ source: {
+ if (securityType(security) === "unsecured") {
+ if (strength < 30)
+ source = "components/images/wifi1.png"
+ else if (strength >= 30 && strength < 50)
+ source = "components/images/wifi2.png"
+ else if (strength >= 50 && strength < 70)
+ source = "components/images/wifi3.png"
+ else
+ source = "components/images/wifi4.png"
+ } else {
+ if (strength < 30)
+ source = "components/images/wifi1-lock.png"
+ else if (strength >= 30 && strength < 50)
+ source = "components/images/wifi2-lock.png"
+ else if (strength >= 50 && strength < 70)
+ source = "components/images/wifi3-lock.png"
+ else
+ source = "components/images/wifi4-lock.png"
+ }
+ }
+ }
+
+ Column {
+ anchors.left: icon.right
+ anchors.leftMargin: 10
+ Text {
+ text: name
+ font.pointSize: 20
+ font.bold: {
+ if ((serviceState === "ready")
+ || serviceState === "online")
+ font.bold = true
+ else
+ font.bold = false
+ }
+
+ color: {
+ if ((serviceState === "ready")
+ || serviceState === "online")
+ color = "#00ff00"
+ else
+ color = "#ffffff"
+ }
+ }
+
+ Text {
+ //text: serviceState + ", RSSI: " + strength + security
+ /* text: {
+ if ((serviceState === "ready") || serviceState === "online")
+ text = "signal " + signalStrength(strength) + ", " + "connected" + ", " + address
+ else
+ text = "signal " + signalStrength(strength) + ", " + securityType(security) + " network" + ", " + serviceState
+ }*/
+ visible: ((serviceState === "ready")
+ || serviceState === "online") ? true : false
+ text: "connected, " + address
+ font.pointSize: 18
+ color: "#ffffff"
+ font.italic: true
+ }
+ }
+
+ Button {
+ id: connectButton
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+
+ width: 250
+
+ //text: ""
+
+ //anchors.rightMargin: 40
+ //buttonText: "Connect"
+ // style: ButtonStyle {
+ // label: Text {
+ // text: control.text
+ // color: "blue"
+ // text: control.text
+ // }
+ //}
+
+ // buttonText: {
+
+ // if ((serviceState === "ready") || serviceState === "online")
+ // buttonText = "Forget"
+ // else
+ // buttonText = "Connect"}
+ MouseArea {
+ anchors.fill: parent
+
+ Text {
+ anchors.fill: parent
+ id: buttonTextLabel
+ font.pixelSize: 15
+ font.bold: true
+ color: "black"
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: {
+ if ((serviceState === "ready")
+ || serviceState === "online")
+ text = "Forget"
+ else
+ text = "Connect"
+ }
+ }
+
+ onClicked: {
+
+ //connectButton.border.color = "steelblue"
+ if ((serviceState === "ready")
+ || serviceState === "online") {
+
+ //means we are connected
+ console.log("Disconnecting from", index, " ,", name)
+ request(wifiAPIpath + 'disconnect?network=' + index,
+ function (o) {
+
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ } else {
+ console.log("Conect to", index, " ,", name)
+
+ //passwordDialog.open()
+ request(wifiAPIpath + 'connect?network=' + index,
+ function (o) {
+
+ // log the json response
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ }
+ }
+ }
+ }
+
+ Button {
+ id: passwordButton
+ anchors.top: parent.top
+ anchors.right: parent.right
+ width: 40
+ visible: (securityType(security) === "unsecured") ? false : true
+
+ //anchors.rightMargin: connectButton.width + 5
+ //buttonText: "Connect"
+ text: {
+ "Key" //or some icon?
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ onClicked: {
+
+ //connectButton.border.color = "steelblue"
+ passwordInputText.visible = true
+ connectButton.visible = false
+ passwordValidateButton.visible = true
+
+ System.showKeyboard = visible
+
+ //passwordInputText.o
+ periodicRefresh.stop()
+
+ var passkey = passwordInputText.text.valueOf()
+
+ //var passkey = 'randompassword'
+ console.log("Disconnecting from", index, " ,", name)
+ }
+ }
+ }
+
+ Button {
+ id: passwordValidateButton
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.rightMargin: connectButton.width + 5
+ width: 40
+ visible: false
+
+ //anchors.rightMargin: connectButton.width + 5
+ //buttonText: "Connect"
+ text: {
+ "ok" //or some icon?
+ }
+
+ MouseArea {
+ anchors.fill: parent
+
+ onClicked: {
+ //passwordInputText = ""
+ var passkey = passwordInputText.text.valueOf()
+ console.log("Validating", passkey)
+ System.showKeyboard = false
+
+ console.log("Passkey is", passkey)
+ request(wifiAPIpath + 'security?passkey=' + passkey,
+ function (o) {
+
+ showRequestInfo(o.responseText)
+ console.log(o.responseText)
+ })
+ passwordValidateButton.visible = false
+ passwordInputText.visible = false
+ connectButton.visible = true
+
+ keyboard.currentString = ""
+
+ periodicRefresh.start()
+ }
+ }
+ }
+
+ TextInput {
+ id: passwordInputText
+ anchors.top: parent.top
+ anchors.right: parent.right
+ anchors.rightMargin: 5
+
+ font.pointSize: 15
+ color: "#ffffff"
+
+ width: connectButton.width
+ visible: false
+ text: keyboard.currentString
+ }
+ }
+ }
+
+ ListView {
+ width: parent.width
+ anchors.top: parent.top
+ anchors.topMargin: 70
+ anchors.bottom: parent.bottom
+ anchors.bottomMargin: 150
+ model: networkList //WifiList {}
+ delegate: wifiDevice
+ clip: true
+ }
+
+ //Timer for periodic refresh; this is BAD solution, need to figure out how to subscribe for events
+ Timer {
+ id: periodicRefresh
+ interval: 5000 // 5seconds
+ onTriggered: {
+
+ networkList.clear()
+
+ request(wifiAPIpath + 'scan_result', function (o) {
+
+ // log the json response
+ console.log(o.responseText)
+
+ // translate response into object
+ var jsonObject = eval('(' + o.responseText + ')')
+
+ var jsonObjectNetworks = eval('(' + JSON.stringify(
+ jsonObject.response) + ')')
+
+ console.log("WiFi list refreshed")
+
+ //console.log(jsonObject.response)
+ for (var i = 0; i < jsonObjectNetworks.length; i++) {
+
+ networkList.append({
+ number: jsonObjectNetworks[i].Number,
+ name: jsonObjectNetworks[i].ESSID,
+ strength: jsonObjectNetworks[i].Strength,
+ serviceState: jsonObjectNetworks[i].State,
+ security: jsonObjectNetworks[i].Security,
+ address: jsonObjectNetworks[i].IPAddress
+ })
+ // console.log(jsonObjectNetworks[i].Number,
+ // jsonObjectNetworks[i].ESSID,
+ // jsonObjectNetworks[i].Strength,
+ // jsonObjectNetworks[i].State,
+ // jsonObjectNetworks[i].Security)
+ }
+ })
+
+ start()
+ }
+ }
+
+ Keyboard {
+ id: keyboard
+ y: System.showKeyboard ? parent.height - height : parent.height
+ width: parent.width
+ }
+}
diff --git a/wifi-api.c b/wifi-api.c
new file mode 100755
index 0000000..2d9748f
--- /dev/null
+++ b/wifi-api.c
@@ -0,0 +1,489 @@
+/* Copyright 2016 ALPS ELECTRIC 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.
+*/
+
+/**
+ * file
+ *
+ * \brief Implementation of WiFi Binder for AGL's App Framework
+ *
+ * \author ALPS Electric
+ */
+
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <json-c/json.h>
+#include <afb/afb-binding.h>
+
+#include "wifi-api.h"
+#include "wifi-connman.h"
+
+/*
+ * the interface to afb-daemon
+ */
+const struct afb_binding_interface *afbitf;
+
+static int need_password_flag = 0;
+static int password_not_correct_flag = 0;
+
+char *passkey;
+callback ptr_my_callback;
+
+GSList *wifi_list = NULL;
+
+/**
+ * \brief Read out the passkey from the use and pass it to Agent
+ *
+ * \todo Since I do not know how to subscribe for the events from framework,
+ * it is necessary first to register the password http://IP_ADDRESS:PORT/api/wifi-manager/security?passkey=mypassword.
+ * Then this function is called automatically.
+ *
+ *
+ * */
+void passkey_inserted(void) {
+
+ printf("Passkey inserted: %s\n", passkey);
+
+ if (passkey != NULL) {
+
+ registerPasskey(passkey);
+ } else {
+ printf("Please enter the password first\n");
+
+ }
+}
+
+/**
+ * \brief Notify user that password is necessary
+ *
+ * This function is called from the registered agent on RequestInput() call.
+ * \todo Subscribe for this event from GUI.
+ *
+ * */
+void ask_for_passkey(int password_rejected_flag) {
+ //TODO: show network we are asking password for
+ printf("Insert passkey.\n");
+
+ if (!password_rejected_flag) {
+ need_password_flag = 1;
+ password_not_correct_flag = 0;
+ //sleep(1);
+ passkey_inserted();
+
+ }
+
+ else if (password_rejected_flag) {
+ need_password_flag = 1;
+ printf("Password not correct!\n");
+
+ }
+
+}
+
+/**
+ * \brief Insert passkey that will be used for connections to secured AP.
+ *
+ * \TODO Only temporary, user should enter the password on ask_for_passkey() callback
+ *
+ * */
+void wifi_insertpasskey(struct afb_req request) {
+
+ const char *passkey_from_user;
+
+ /* retrieves the argument, expects password string */
+ passkey_from_user = afb_req_value(request, "passkey");
+
+ if (passkey_from_user == NULL) {
+ //TODO:better error message
+ afb_req_fail(request, "failed", "specify a security key");
+
+ } else {
+
+ passkey = g_try_malloc0(256);
+ strcpy(passkey, passkey_from_user);
+ printf("Passkey is %s\n", passkey);
+
+ }
+
+ afb_req_success(request, NULL, NULL);
+}
+
+/**
+ * \brief initialize the binder and activates the WiFi HW, should be called first
+ *
+ * This will fail if
+ * - agent for handling password requests cannot be registered
+ * - some error is returned from connman
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+static void wifi_activate(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+ json_object *jresp;
+ GError *error = NULL;
+
+ if (ptr_my_callback == NULL) {
+
+ printf("Registering callback\n");
+
+ ptr_my_callback = ask_for_passkey;
+ register_callback(ptr_my_callback);
+
+ }
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "activation", json_object_new_string("on"));
+
+ error = do_wifiActivate();
+
+ if (error == NULL) {
+
+ afb_req_success(request, jresp, "Wi-Fi - Activated");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+
+}
+
+/**
+ * \brief deinitialize the binder and activates the WiFi HW
+ *
+ * This will fail if
+ * - agent for handling password requests cannot be unregistered
+ * - some error is returned from connman
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+static void wifi_deactivate(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+
+ json_object *jresp;
+ GError *error = NULL;
+
+ ptr_my_callback = NULL;
+
+ jresp = json_object_new_object();
+ json_object_object_add(jresp, "deactivation", json_object_new_string("on"));
+
+ error = do_wifiDeactivate();
+
+ if (error == NULL) {
+
+ afb_req_success(request, jresp, "Wi-Fi - Activated");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief starts scan
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_scan(struct afb_req request) /*AFB_SESSION_NONE*/
+{
+ GError *error = NULL;
+
+ error = do_wifiScan();
+
+ if (error == NULL) {
+
+ afb_req_success(request, NULL, "Wi-Fi - Scan success");
+
+ } else
+
+ afb_req_fail(request, "failed", error->message);
+
+}
+
+/**
+ * \brief return network list
+ *
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_scanResult(struct afb_req request) /*AFB_SESSION_CHECK*/
+{
+ struct wifi_profile_info *wifiProfile = NULL;
+ GSList *list = NULL;
+ GSList *holdMe = NULL;
+ wifi_list = NULL;
+ char *essid = NULL;
+ char *address = NULL;
+ char *security = NULL;
+ char *state = NULL;
+ int strength = 0;
+ int number = 0;
+ GError *error = NULL;
+
+ error = do_displayScan(&wifi_list); /*Get wifi scan list*/
+ if (error == NULL) {
+ json_object *my_array = json_object_new_array();
+
+ for (list = wifi_list; list; list = list->next) { /*extract wifi scan result*/
+ wifiProfile = (struct wifi_profile_info *) list->data;
+ security = wifiProfile->Security.sec_type;
+ strength = wifiProfile->Strength;
+ //if (essid == NULL || security == NULL)
+ // continue;
+
+ essid = wifiProfile->ESSID == NULL ?
+ "HiddenSSID" : wifiProfile->ESSID;
+ address =
+ wifiProfile->wifiNetwork.IPaddress == NULL ?
+ "unsigned" : wifiProfile->wifiNetwork.IPaddress;
+ state = wifiProfile->state;
+ //TODO: is there a case when security is NULL?
+
+ json_object *int1 = json_object_new_int(number);
+ json_object *int2 = json_object_new_int(strength);
+ json_object *jstring1 = json_object_new_string(essid);
+ json_object *jstring2 = json_object_new_string(security);
+ json_object *jstring3 = json_object_new_string(address);
+ json_object *jstring4 = json_object_new_string(state);
+
+ json_object *jresp = json_object_new_object();
+ json_object_object_add(jresp, "Number", int1);
+ json_object_object_add(jresp, "Strength", int2);
+ json_object_object_add(jresp, "ESSID", jstring1);
+ json_object_object_add(jresp, "Security", jstring2);
+ json_object_object_add(jresp, "IPAddress", jstring3);
+ json_object_object_add(jresp, "State", jstring4);
+
+ printf("The object json: %s\n", json_object_to_json_string(jresp));
+ /*input each scan result into my_array*/
+ json_object_array_add(my_array, jresp);
+ number += 1;
+ }
+ while (list != NULL) {
+ printf("Should be freed");
+ holdMe = list->next;
+ g_free(list);
+ list = holdMe;
+ }
+ afb_req_success(request, my_array, "Wi-Fi - Scan Result is Displayed");
+ } else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief connects to network
+ *
+ * \param[in] request number of network to connect to
+ *
+ * specify number of network to connect to obtained by scan_result() like this,
+ * http://IP_ADDRESS:PORT/api/wifi-manager/connect?network=1
+ */
+void wifi_connect(struct afb_req request) {
+
+ struct wifi_profile_info *wifiProfileToConnect = NULL;
+
+ const char *network;
+ int network_index = 0;
+ GError *error = NULL;
+ GSList *item = NULL;
+
+ /* retrieves the argument, expects the network number */
+ network = afb_req_value(request, "network");
+
+ if (network == NULL)
+ //TODO:better error message
+ afb_req_fail(request, "failed",
+ "specify a network number to connect to");
+
+ else {
+ network_index = atoi(network);
+ printf("Joining network number %d\n", network_index);
+
+ }
+
+ //get information about desired network
+ item = g_slist_nth_data(wifi_list, network_index);
+
+ if (item == NULL) {
+ //Index starts from 1
+ printf("Network with number %d not found.\n", network_index + 1);
+ //TODO:better error message
+ afb_req_fail(request, "failed", "bad arguments");
+ }
+
+ else {
+ wifiProfileToConnect = (struct wifi_profile_info *) item;
+ printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID,
+ wifiProfileToConnect->Strength,
+ wifiProfileToConnect->NetworkPath);
+ //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath);
+ }
+ error = do_connectNetwork(wifiProfileToConnect->NetworkPath);
+
+ if (error == NULL)
+ afb_req_success(request, NULL, NULL);
+
+ else if (password_not_correct_flag) {
+ need_password_flag = 0;
+ password_not_correct_flag = 0;
+ afb_req_fail(request, "password-incorrect", NULL);
+ } else if (need_password_flag) {
+ need_password_flag = 0;
+ afb_req_fail(request, "need-password", NULL);
+
+ } else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief disconnect from network
+ *
+ * \param[in] request number of network to disconnect from
+ *
+ * specify number of network to disconnect from obtained by scan_result() like this,
+ * http://IP_ADDRESS:PORT/api/wifi-manager/discnnect?network=1
+ */
+void wifi_disconnect(struct afb_req request) {
+
+ struct wifi_profile_info *wifiProfileToConnect = NULL;
+
+ const char *network;
+ int network_index = 0;
+ GError *error = NULL;
+ GSList *item = NULL;
+
+ /* retrieves the argument, expects the network number */
+ network = afb_req_value(request, "network");
+
+ if (network == NULL)
+ //TODO:better error message
+ afb_req_fail(request, "failed",
+ "specify a network number to disconnect from");
+
+ else {
+ network_index = atoi(network);
+ printf("Joining network number %d\n", network_index);
+
+ }
+
+ //get information about desired network
+ item = g_slist_nth_data(wifi_list, network_index);
+
+ if (item == NULL) {
+ //Index starts from 1
+ printf("Network with number %d not found.\n", network_index + 1);
+ //TODO:better error message
+ afb_req_fail(request, "failed", "bad arguments");
+ }
+
+ else {
+ wifiProfileToConnect = (struct wifi_profile_info *) item;
+ printf("Name: %s, strength: %d, %s\n", wifiProfileToConnect->ESSID,
+ wifiProfileToConnect->Strength,
+ wifiProfileToConnect->NetworkPath);
+ //printf ("Connecting to %s\n", wifiProfileToConnect->NetworkPath);
+ }
+ error = do_disconnectNetwork(wifiProfileToConnect->NetworkPath);
+
+ if (error == NULL)
+ afb_req_success(request, NULL, NULL);
+ else
+ afb_req_fail(request, "failed", error->message);
+}
+
+/**
+ * \brief return current status of connection
+ *
+ * \return result of the request, either "success" or "failed" with description
+ */
+void wifi_status(struct afb_req request) {
+ int error = 0;
+ wifi_list = NULL;
+ struct wifiStatus *status;
+ json_object *jresp = json_object_new_object();
+
+ status = g_try_malloc0(sizeof(struct wifiStatus));
+ error = wifi_state(status); /*get current status of power and connection*/
+ if (!error) {
+ if (status->state == 0) {/*Wi-Fi is OFF*/
+ json_object_object_add(jresp, "Power",
+ json_object_new_string("OFF"));
+ //json_object_object_add(jresp, "Connection", json_object_new_string("Disconnected"));
+ printf("Wi-Fi OFF\n");
+ } else {/*Wi-Fi is ON*/
+ json_object_object_add(jresp, "Power",
+ json_object_new_string("ON"));
+ if (status->connected == 0) {/*disconnected*/
+ json_object_object_add(jresp, "Connection",
+ json_object_new_string("Disconnected"));
+ printf("Wi-Fi ON - Disconnected \n");
+ } else {/*Connected*/
+ json_object_object_add(jresp, "Connection",
+ json_object_new_string("Connected"));
+ printf("Wi-Fi ON - Connected \n");
+ }
+ }
+ afb_req_success(request, jresp, "Wi-Fi - Connection Status Checked");
+ } else {
+ afb_req_fail(request, "failed", "Wi-Fi - Connection Status unknown");
+ }
+}
+
+void wifi_reconnect() {
+ /*TBD*/
+}
+
+
+
+/*
+ * array of the verbs exported to afb-daemon
+ */
+static const struct afb_verb_desc_v1 binding_verbs[] = {
+/* VERB'S NAME SESSION MANAGEMENT FUNCTION TO CALL SHORT DESCRIPTION */
+{ .name = "activate", .session = AFB_SESSION_NONE, .callback = wifi_activate, .info = "Activate Wi-Fi" },
+{ .name = "deactivate", .session = AFB_SESSION_NONE, .callback = wifi_deactivate, .info ="Deactivate Wi-Fi" },
+{ .name = "scan", .session = AFB_SESSION_NONE, .callback = wifi_scan, .info = "Scanning Wi-Fi" },
+{ .name = "scan_result",.session = AFB_SESSION_NONE, .callback = wifi_scanResult, .info = "Get scan result Wi-Fi" },
+{ .name = "connect", .session = AFB_SESSION_NONE, .callback = wifi_connect, .info ="Connecting to Access Point" },
+{ .name = "status", .session = AFB_SESSION_NONE, .callback = wifi_status, .info ="Check connection status" },
+{ .name = "disconnect", .session = AFB_SESSION_NONE, .callback = wifi_disconnect, .info ="Disconnecting connection" },
+{ .name = "reconnect", .session = AFB_SESSION_NONE, .callback = wifi_reconnect, .info ="Reconnecting to Access Point" },
+{ .name = "security", .session = AFB_SESSION_NONE, .callback = wifi_insertpasskey, .info ="Insert passkey" },
+
+{ .name = NULL } /* marker for end of the array */
+};
+
+/*
+ * description of the binding for afb-daemon
+ */
+static const struct afb_binding binding_description = {
+/* description conforms to VERSION 1 */
+.type = AFB_BINDING_VERSION_1, .v1 = { /* fills the v1 field of the union when AFB_BINDING_VERSION_1 */
+.prefix = "wifi-manager", /* the API name (or binding name or prefix) */
+.info = "wifi API", /* short description of of the binding */
+.verbs = binding_verbs /* the array describing the verbs of the API */
+} };
+
+/*
+ * activation function for registering the binding called by afb-daemon
+ */
+const struct afb_binding *afbBindingV1Register(
+ const struct afb_binding_interface *itf) {
+ afbitf = itf; // records the interface for accessing afb-daemon
+ return &binding_description; // returns the description of the binding
+}
+
diff --git a/wifi-api.h b/wifi-api.h
new file mode 100755
index 0000000..429211b
--- /dev/null
+++ b/wifi-api.h
@@ -0,0 +1,38 @@
+/* Copyright 2016 ALPS ELECTRIC 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 WIFI_API_H
+#define WIFI_API_H
+
+/* global plugin handle, should store everything we may need */
+typedef struct {
+ int devCount;
+} pluginHandleT;
+
+/* private client context [will be destroyed when client leaves] */
+typedef struct {
+ unsigned char activate;
+ unsigned char connected;
+} wifiCtxHandleT;
+
+
+struct scan_list_info {
+ int number;
+ char *SSID;
+ char *Security;
+ int Strength;
+};
+
+#endif /* AUDIO_API_H */
diff --git a/wifi-connman.c b/wifi-connman.c
new file mode 100755
index 0000000..74d2be7
--- /dev/null
+++ b/wifi-connman.c
@@ -0,0 +1,354 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+//#include <dbus/dbus.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#include "wifi-api.h"
+#include "wifi-connman.h"
+
+static __thread struct security_profile Security = { NULL, NULL, NULL, NULL, 0,
+ 0 };
+
+int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile) {
+ GVariant *var = NULL;
+ GVariant *subvar = NULL;
+ GVariantIter *array;
+ const gchar *key = NULL;
+ const gchar *subkey = NULL;
+ const gchar *value_char = NULL;
+ GVariantIter *content_sub;
+ int value_int;
+ gsize length;
+
+ while (g_variant_iter_loop(content, "{sv}", &key, &var)) {
+ if (g_strcmp0(key, "Name") == 0) {
+ value_char = g_variant_get_string(var, &length);
+ wifiProfile->ESSID = (char *) value_char;
+ } else if (g_strcmp0(key, "Security") == 0) {
+ g_variant_get(var, "as", &content_sub);
+ while (g_variant_iter_loop(content_sub, "s", &value_char)) {
+ if (g_strcmp0(value_char, "none") == 0)
+ wifiProfile->Security.sec_type = "Open";
+ else if (g_strcmp0(value_char, "wep") == 0)
+ wifiProfile->Security.sec_type = "WEP";
+ else if (g_strcmp0(value_char, "psk") == 0)
+ wifiProfile->Security.sec_type = "WPA-PSK";
+ else if (g_strcmp0(value_char, "ieee8021x") == 0)
+ wifiProfile->Security.sec_type = "ieee8021x";
+ else if (g_strcmp0(value_char, "wpa") == 0)
+ wifiProfile->Security.sec_type = "WPA-PSK";
+ else if (g_strcmp0(value_char, "rsn") == 0)
+ wifiProfile->Security.sec_type = "WPA2-PSK";
+ else if (g_strcmp0(value_char, "wps") == 0)
+ wifiProfile->Security.wps_support = 1;
+ else
+ Security.sec_type = "Open";
+ }
+ } else if (g_strcmp0(key, "Strength") == 0) {
+ value_int = (unsigned int) g_variant_get_byte(var);
+ wifiProfile->Strength = value_int;
+ } else if (g_strcmp0(key, "State") == 0) {
+ value_char = g_variant_get_string(var, &length);
+ wifiProfile->state = (char *) value_char;
+ } else if (g_strcmp0(key, "IPv4") == 0) {
+ g_variant_get(var, "a{sv}", &array);
+ while (g_variant_iter_loop(array, "{sv}", &subkey, &subvar)) {
+ if (g_strcmp0(subkey, "Method") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ if (g_strcmp0(value_char, "dhcp") == 0)
+ wifiProfile->wifiNetwork.method = "dhcp";
+ else if (g_strcmp0(value_char, "manual") == 0)
+ wifiProfile->wifiNetwork.method = "manual";
+ else if (g_strcmp0(value_char, "fixed") == 0)
+ wifiProfile->wifiNetwork.method = "fix";
+ else if (g_strcmp0(value_char, "off") == 0)
+ wifiProfile->wifiNetwork.method = "off";
+ } else if (g_strcmp0(subkey, "Address") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ wifiProfile->wifiNetwork.IPaddress = (char *) value_char;
+ } else if (g_strcmp0(subkey, "Netmask") == 0) {
+ value_char = g_variant_get_string(subvar, &length);
+ wifiProfile->wifiNetwork.netmask = (char *) value_char;
+ }
+ }
+ }
+ }
+ //printf ("SSID= %s, security= %s, Strength= %d, wps support= %d\n", wifiProfile->ESSID, wifiProfile->Security.sec_type, wifiProfile->Strength, wifiProfile->Security.wps_support);
+ return 0;
+}
+
+int wifi_state(struct wifiStatus *status) {
+ GError *error = NULL;
+ GVariant *message = NULL;
+ GVariantIter *array;
+ GDBusConnection *connection;
+ GVariant *var = NULL;
+ const gchar *key = NULL;
+ gboolean value_bool;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return -1;
+ }
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_TECHNOLOGY_PATH, CONNMAN_TECHNOLOGY_INTERFACE, "GetProperties",
+ NULL, NULL, G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+ if (message == NULL) {
+ printf("message is NULL");
+ return -1;
+ }
+ g_variant_get(message, "(a{sv})", &array);
+ while (g_variant_iter_loop(array, "{sv}", &key, &var)) {
+ if (g_strcmp0(key, "Powered") == 0) {
+ value_bool = g_variant_get_boolean(var);
+ if (value_bool)
+ status->state = 1;
+ else
+ status->state = 0;
+ } else if (g_strcmp0(key, "Connected") == 0) {
+ value_bool = g_variant_get_boolean(var);
+ if (value_bool)
+ status->connected = 1;
+ else
+ status->connected = 0;
+ }
+ }
+ g_variant_iter_free(array);
+ g_variant_unref(message);
+
+ return 0;
+}
+
+GError* do_wifiActivate() {
+ GVariant *params = NULL;
+ params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(TRUE));
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ //create the agent to handle security
+ error = create_agent(connection);
+
+ if (error)
+ //This is fatal error, without agent secured networks can not be handled
+ return error;
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty",
+ params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Power ON succeeded\n");
+ return NULL;
+ }
+
+}
+
+GError* do_wifiDeactivate() {
+ GVariant *params = NULL;
+ params = g_variant_new("(sv)", "Powered", g_variant_new_boolean(FALSE));
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ //create the agent to handle security
+ error = stop_agent(connection);
+
+ if (error) {
+ printf("Error while unregistering the agent, ignoring.");
+
+ }
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty",
+ params, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, &error);
+
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Power OFF succeeded\n");
+ return NULL;
+ }
+}
+
+GError* do_wifiScan() {
+ GDBusConnection *connection;
+ GError *error = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+
+ g_dbus_connection_call(connection, CONNMAN_SERVICE,
+ CONNMAN_WIFI_TECHNOLOGY_PREFIX, CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL,
+ NULL, G_DBUS_CALL_FLAGS_NONE, DBUS_REPLY_TIMEOUT, NULL, NULL, &error);
+ if (error) {
+ printf("error: %d:%s\n", error->code, error->message);
+
+ return error;
+ }
+
+ else {
+ printf("Scan succeeded\n");
+ return NULL;
+ }
+}
+
+GError* do_displayScan(GSList **wifi_list) {
+ GError *error = NULL;
+ GVariant *message = NULL;
+ GVariantIter *array;
+ gchar *object;
+ GVariantIter *content = NULL;
+ GDBusConnection *connection;
+ struct wifi_profile_info *wifiProfile = NULL;
+
+ /*connection = gdbus_conn->connection;*/
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+ if (connection == NULL) {
+ printf("GDBusconnection is NULL");
+ return error;
+ }
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, "GetServices", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+ if (message == NULL) {
+ printf("message is NULL");
+ return error;
+ }
+ g_variant_get(message, "(a(oa{sv}))", &array);
+ while (g_variant_iter_loop(array, "(oa{sv})", &object, &content)) {
+ if (g_str_has_prefix(object,
+ CONNMAN_WIFI_SERVICE_PROFILE_PREFIX) == TRUE) {
+ wifiProfile = g_try_malloc0(sizeof(struct wifi_profile_info));
+
+ extract_values(content, wifiProfile);
+ wifiProfile->NetworkPath = g_try_malloc0(strlen(object));
+ strcpy(wifiProfile->NetworkPath, object);
+ printf(
+ "SSID= %s, security= %s, path= %s, Strength= %d, wps support= %d\n",
+ wifiProfile->ESSID, wifiProfile->Security.sec_type,
+ wifiProfile->NetworkPath, wifiProfile->Strength,
+ wifiProfile->Security.wps_support);
+ printf("method= %s, ip address= %s, netmask= %s\n",
+ wifiProfile->wifiNetwork.method,
+ wifiProfile->wifiNetwork.IPaddress,
+ wifiProfile->wifiNetwork.netmask);
+ *wifi_list = g_slist_append(*wifi_list,
+ (struct wifi_profile_info *) wifiProfile);
+ }
+ }
+ g_variant_iter_free(array);
+
+ return NULL;
+}
+
+GError* do_connectNetwork(gchar *networkPath) {
+
+ printf("Connecting to: %s\n", networkPath);
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+ GDBusConnection *connection;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ networkPath, CONNMAN_SERVICE_INTERFACE, "Connect", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT_SHORT, NULL, &error);
+
+ //printf("message error %s\n", message);
+ //TODO: do we need retunrn value in message
+
+ if (error) {
+ printf("do_connectNetwork error: %s\n", error->message);
+ return error;
+ } else {
+ printf("Connection succeeded\n");
+ return NULL;
+ }
+
+}
+
+GError* do_disconnectNetwork(gchar *networkPath) {
+
+ printf("Connecting to: %s\n", networkPath);
+
+ GVariant *message = NULL;
+ GError *error = NULL;
+ GDBusConnection *connection;
+
+ connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);
+
+ message = g_dbus_connection_call_sync(connection, CONNMAN_SERVICE,
+ networkPath, CONNMAN_SERVICE_INTERFACE, "Disconnect", NULL, NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_REPLY_TIMEOUT, NULL, &error);
+
+ //TODO: do we need return value in message
+
+ if (error) {
+ printf("error: %s\n", error->message);
+ return error;
+ } else {
+ printf("Disconnected\n");
+ return NULL;
+ }
+
+}
+
+void registerPasskey(gchar *passkey) {
+
+ printf("Passkey: %s\n", passkey);
+ sendPasskey(passkey);
+
+}
+
diff --git a/wifi-connman.h b/wifi-connman.h
new file mode 100755
index 0000000..bd83821
--- /dev/null
+++ b/wifi-connman.h
@@ -0,0 +1,126 @@
+/* Copyright 2016 ALPS ELECTRIC 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 <dlog.h>
+#include <glib.h>
+#include <stdlib.h>
+#include <gio/gio.h>
+#include <glib-object.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Maximum Profile Count */
+#define CONNMAN_MAX_BUFLEN 512
+
+#define CONNMAN_STATE_STRLEN 16
+
+#define CONNMAN_SERVICE "net.connman"
+#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager"
+#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology"
+#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service"
+#define CONNMAN_PROFILE_INTERFACE CONNMAN_SERVICE ".Profile"
+#define CONNMAN_COUNTER_INTERFACE CONNMAN_SERVICE ".Counter"
+#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
+#define CONNMAN_AGENT_INTERFACE CONNMAN_SERVICE ".Agent"
+
+#define CONNMAN_MANAGER_PATH "/"
+#define CONNMAN_PATH "/net/connman"
+#define CONNMAN_TECHNOLOGY_PATH "/net/connman/technology/wifi"
+
+/** ConnMan technology and profile prefixes for ConnMan 0.78 */
+
+#define CONNMAN_WIFI_TECHNOLOGY_PREFIX CONNMAN_PATH "/technology/wifi"
+#define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/wifi_"
+
+#define WIFI_ESSID_LEN 128
+#define WIFI_MAX_WPSPIN_LEN 8
+#define WIFI_BSSID_LEN 17
+#define WIFI_MAX_PSK_PASSPHRASE_LEN 65
+#define WIFI_MAX_WEP_KEY_LEN 26
+
+#define AGENT_PATH "/net/connman/Agent"
+#define AGENT_SERVICE "org.agent"
+
+#define DBUS_REPLY_TIMEOUT (120 * 1000)
+#define DBUS_REPLY_TIMEOUT_SHORT (10 * 1000)
+
+
+struct gdbus_connection_data_s{
+ GDBusConnection *connection;
+ int conn_ref_count;
+ GCancellable *cancellable;
+ void *handle_libnetwork;
+};
+
+
+struct wifiStatus {
+ unsigned int state;
+ unsigned int connected;
+};
+
+struct security_profile{
+ char *sec_type;
+ char *enc_type;
+ char *wepKey;
+ char *pskKey;
+ unsigned int PassphraseRequired;
+ unsigned int wps_support;
+};
+
+struct wifi_net{
+ char *method;
+ char *IPaddress;
+ char *netmask;
+};
+
+struct wifi_profile_info{
+ char *ESSID;
+ char *NetworkPath;
+ char *state;
+ unsigned int Strength;
+ struct security_profile Security;
+ struct wifi_net wifiNetwork;
+};
+
+//typedef void(*callback)(void);
+typedef void(*callback)(int password_rejected_flag);
+void register_callback(callback ptr);
+
+
+int extract_values(GVariantIter *content, struct wifi_profile_info* wifiProfile);
+int wifi_state(struct wifiStatus *status);
+GError* do_wifiActivate();
+GError* do_wifiDeactivate();
+GError* do_wifiScan();
+GError* do_displayScan(GSList **wifi_list);
+GError* do_connectNetwork(gchar *object);
+GError* do_disconnectNetwork(gchar *object);
+
+GError* create_agent(GDBusConnection *connection);
+GError* stop_agent(GDBusConnection *connection);
+
+
+void registerPasskey(gchar *object);
+GError* sendPasskey(gchar *object);
+
+GError* do_initialize();
+GError* do_initialize();
+
+
+
+
+