From: Szymon Jastrzebski Date: Thu, 9 Nov 2017 09:28:52 +0000 (+0100) Subject: [Docs] Updating docs/src for Tizen 4.0 X-Git-Tag: submit/tizen_4.0/20171117.110318^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4bf4993dd07fe2e219142ea4b2c717ac223d605c;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [Docs] Updating docs/src for Tizen 4.0 + adding conversion table + adding guide for example WIDL code style Change-Id: I59a6d885b567a848c546f0ef3e660057558bfa58 Signed-off-by: Szymon Jastrzebski --- diff --git a/doc/README.md b/doc/README.md index 8c084bd0..68c9b63b 100644 --- a/doc/README.md +++ b/doc/README.md @@ -4,7 +4,7 @@ HTML is generated from markdown files by: npm install # only once to install required packages npm run-script generate -PDF is generated by "Print to PDF" in Chrome browser. +PDF is generated by "Print to PDF" (CTRL+P) in Chrome browser. ===================================================== Troubleshooting: diff --git a/doc/Tizen Avengers - WebApi Guidelines.pdf b/doc/Tizen Avengers - WebApi Guidelines.pdf index ac6172fc..83cce2c4 100644 Binary files a/doc/Tizen Avengers - WebApi Guidelines.pdf and b/doc/Tizen Avengers - WebApi Guidelines.pdf differ diff --git a/doc/Type conversion table.xlsx b/doc/Type conversion table.xlsx new file mode 100644 index 00000000..e29e154a Binary files /dev/null and b/doc/Type conversion table.xlsx differ diff --git a/doc/html/index.html b/doc/html/index.html index 1328643e..7253e5ab 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -12,7 +12,7 @@
- +
Generated by Doctor, MD @@ -35,49 +35,55 @@ 0.1.0 2015-05-15 Initial Draft -Wojciech Kosowicz
w.kosowicz@samsung.com +Wojciech Kosowicz
w.kosowicz@samsung.com 0.2.0 2015-05-22 Extended version -Pawel Kaczmarek
p.kaczmarek3@samsung.com +Pawel Kaczmarek
p.kaczmarek3@samsung.com 0.2.1 2015-06-01 Proofreading -Rafal Galka
r.galka@samsung.com +Rafal Galka
r.galka@samsung.com 0.3.0 2015-06-08 Supplemented C++ implementation guide -Rafal Galka
r.galka@samsung.com +Rafal Galka
r.galka@samsung.com 0.4.0 2015-06-16 Guideline -Pawel Kaczmarek
p.kaczmarek3@samsung.com +Pawel Kaczmarek
p.kaczmarek3@samsung.com 0.5.0 2015-06-18 Devel package -Pawel Kaczmarek
p.kaczmarek3@samsung.com +Pawel Kaczmarek
p.kaczmarek3@samsung.com 0.5.1 2015-06-24 Add info about WAPIOven.py -Pawel Kaczmarek
p.kaczmarek3@samsung.com +Pawel Kaczmarek
p.kaczmarek3@samsung.com 0.6.0 2016-10-28 update devel package for tizen 3.0 -Annie Park
hj.na.park@samsung.com +Annie Park
hj.na.park@samsung.com + + +0.7.0 +2017-11-09 +Update guidelines for Tizen 4.0 +Szymon Jastrzębski
s.jastrzebsk@partner.samsung.com @@ -90,9 +96,12 @@ Each plugin should be written with great attention on JavaScript.

Languages

C++, JavaScript

Coding style

-

Use Google style guide, -C++: http://google-styleguide.googlecode.com/svn/trunk/cppguide.html

-

JavaScript: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml

+

Use Google style guides (with small exceptions):

+

C++: https://google.github.io/styleguide/cppguide.html

+

JavaScript: https://google.github.io/styleguide/jsguide.html

+

On branches tizen_3.0 and higher, the C++ and JavaScript files are formatted using scripts, +which its usage is described in the Format code section of this document. +The section also describes where the exceptions from Google coding style are defined.

API guide

Tizen Web Device API Guide Lines.pptx http://platform.sec.samsung.net/slp/Tizen/Tizen%20Managed%20API/Web%20Device%20API/Tizen%20Web%20Device%20API%20Guide%20Lines.pptx

@@ -105,15 +114,15 @@ C++: h $ cd webapi-plugins $ git checkout origin/tizen_2.4 -

For Tizen 3.0

-
$ git clone ssh://<user.id>@168.219.209.56:29418/framework/web/webapi-plugins
+

For Tizen 3.0 and higher

+
$ git clone ssh://<user.id>@review.tizen.org:29418/platform/core/api/webapi-plugins && scp -p -P 29418 <user.id>@review.tizen.org:hooks/commit-msg webapi-plugins/.git/hooks/
 $ cd webapi-plugins
-$ git checkout origin/tizen_3.0
+$ git checkout origin/tizen_<tizen_version>
 

License and Boilerplate

Use this boilerplate in every new created source files.

/*
- * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) <year of file creation> Samsung Electronics Co., Ltd All Rights Reserved
  *
  *    Licensed under the Apache License, Version 2.0 (the "License");
  *    you may not use this file except in compliance with the License.
@@ -141,13 +150,25 @@ $ git checkout origin/tizen_3.0
 
  • <pluginname>_instance.h
  • <pluginname>_instance.cc
  • +

    Additionally, plugins may contain below structure, depending on the WIDL specification file:

    +
      +
    • <pluginname>_client.h
    • +
    • <pluginname>_client.cc
    • +
    • <pluginname>_server.h
    • +
    • <pluginname>_server.cc
    • +
    • <pluginname>_service.h
    • +
    • <pluginname>_service.cc
    • +
    • <pluginname>_util.h
    • +
    • <pluginname>_util.cc
    • +
    +

    and other files with similar naming-convention needed by the developer.

    Spec file

    Spec file (webapi-plugins.spec) kept inside packaging/ directory -is build specification file used by RPM packaging system where variables are defined. +is a build specification file used by RPM packaging system where variables are defined. Those variables can be used to include or exclude particular modules from build for each profile (mobile, TV, wearable).

    Manifest file

    -

    Each RPM package must have a manifest file where developers can specify the access control domain +

    Each RPM package must have a manifest file, where developers can specify the access control domain in which their application should be running and potentially additional security policies for the application. It is necessary to build the project. The manifest file (webapi-plugins.manifest) is located in the root directory of the project.

    @@ -168,7 +189,7 @@ These files are responsible for communication between JavaScript layer and Nativ This file contains all methods required by each API. All operation should be done by JavaScript as much as possible. If JavaScript can do something, it should do it. -This file is responsible for checking arguments, calling C++ methods etc. +This file is responsible for checking and validating arguments, calling C++ methods etc.

    Plugin flow

    Plugin flow

    @@ -178,11 +199,26 @@ This file is responsible for checking arguments, calling C++ methods etc. This information consists of type of call (asynchronous, synchronous) arguments given by user, any additional information that is required to successfully acquire required data. Data is sent in form of JSON. -
  • C++ parses acquired JSON. After the data is processed. Appropriate platform +
  • C++ parses acquired JSON. After the data is processed, appropriate platform functions are called with the specified arguments.
  • Platform returns specified values to C++ layer.
  • -
  • Another JSON is formed. It consists of data that was acquired from platform.
  • +
  • Another JSON is formed. It consists of data that was acquired from platform. +The data is sent to JavaScript layer.
  • +

    Tizen Unified

    +

    With Tizen 4.0 an idea of Tizen Unified was introduced.

    +

    Before Tizen 4.0, each profile specified in .gbs.conf file defined the package repositories +for a single device type and a particular architecture.

    +

    Since Tizen 4.0, each GBS profile is associated with a particular architecture and all device types.

    +

    Each device with given profile and architecture requires to have at least 2 RPM files installed:

    +
    webapi-plugins-x.y-z.ARCH.rpm
    +webapi-plugins-profile_PROFILE_NAME-x.y-z.ARCH.rpm
    +
    +

    However, emulators require to have 3 RPM files installed:

    +
    webapi-plugins-x.y-z.i686.rpm
    +webapi-plugins-profile_PROFILE_NAME-x.y-z.i686.rpm
    +webapi-plugins-PROFILE_NAME-extension-emulator-x.y-z.i686.rpm
    +

    WIDL

    Conventions

    Currently WIDL version that is used in Samsung is described here: http://www.w3.org/TR/WebIDL/. @@ -212,7 +248,7 @@ In interface definition you can put following members:

    can be changed, if it is not read only.
  • Operation: Interface member, which represents method inside object. It is a function of programming language, which can be executed and returns a result.
  • -
  • Special operation: Performs a specific task. i.e. deleter, getter
  • +
  • Special operation: Performs a specific task. i.e. deleter, getter.
  • Static operation: It is not called for a specific instance of the interface, is called for static object regardless of an instance creation. It is connected with the interface itself.
  • @@ -238,8 +274,8 @@ It is connected with the interface itself.
    Tizen implements ManagerObject
     

    To provide actual implementations of ManagerObject, instance of its Manager interface definition has to be made. Inside this Manager interface all attributes -and functions that will be available form manager namespace, should be defined. -There can be attributes which are other interfaces, operations and everything +and functions that will be available from manager namespace, should be defined. +There can be attributes, which are other interfaces, operations and everything that interfaces allows.

    Additional interface can be available as a standalone types not connected to global namespace. Those are either obtained from operation of other interfaces @@ -270,7 +306,10 @@ lacks of keyword FunctionOnly.

    void secondmethod(type somearg2, ... ); any additional methods... }; -

    Example

    +

    Example code style

    +

    Coding style for example codes put in the between \code and \endcode tags +should be written with respect to rules described in the Appendix B.

    +

    Example

    Example of WIDL file:

    module Sample {
     
    @@ -301,6 +340,7 @@ lacks of keyword FunctionOnly.

    };

    Tools

    Generate stub code

    +

    The generator is no longer maintained.

    To generate stub files from the widl you can use stub generator located in tools/skeleton_generator/ directory and run the python command:

    $ python WAPIOven.py -d <stub code destination directory name> <widl directory/pluginname>.widl
    @@ -321,7 +361,7 @@ $ python WAPIOven.py -d ../../src/notification/ /web-device-api/web/widl/tizen/n
     

    WIDL files can be found in the project repository:

    $ git clone ssh://<username>@168.219.209.56:29418/doc/web-device-api
     
    -

    The widl files are placed in: web-device-api/web/widl/tizen/

    +

    The widl files are placed in: web-device-api/web/widl/tizen/ directory.

    Stub files generated by above command:

    <pluginname>_api.js
     <pluginname>_extension.h
    @@ -350,11 +390,33 @@ plugin directory and place JavaScript files.

    To merge all JavaScript files tools/mergejs.py file is used. This script merge all files mentioned in <pluginname>_api.js file into one file before build process.

    +

    Format code

    +

    To format code use scripts provided in the tools/codestyle directory.

    +

    cpplint is used to validate C++ and eslint for JavaScript files.

    +

    Currently, the JavaScript validator and formatter seems to be a little buggy, +thus it is not recommended to use.

    +

    The developer needs to have python, node.js, eslint, Closure Linter and clang-format installed.

    +

    It is worth to make life easier by creating symbolic link to clang-format.

    +
    sudo ln -s /usr/bin/clang-format-<clang format version> /usr/bin/clang-format
    +
    +

    For convenience, in the root of the project links were provided for easier access:

    +
      +
    • code_format -> tools/codestyle/code_formatter.sh
    • +
    • code_validate -> tools/codestyle/code_validation.sh
    • +
    +

    Those scripts consist of configuration for rules regarding the Google style guides, with few exceptions.

    +

    To format and validate C++ and JavaScript code run in the root of the project:

    +
    ./code_validate -a # -a for all, -c for C++, -js for JavaScript files
    +./code_format -a   # use -h or --help for help
    +
    +

    The scripts also accept a path to module's directory. +By default every directory module in the src directory is used.

    +

    For more details, please see tools/codestyle/README file.

    +

    This rule concerns to branches tizen_3.0 and above.

    Implementation - JavaScript

    Each plugin contains JavaScript files. This is the place where user input is -being processed validated before send to C++ layer.

    -

    Badge API will be used to show the creation of JavaScript file (lot of content -of this file will be already generated via Stub Generator).

    +being processed validated before sending to C++ layer.

    +

    Badge API will be used to show the creation of JavaScript file.

    Interface creation

    The WIDL of BadgeManager – main entity that holds all the API methods looks like following:

    @@ -406,12 +468,12 @@ var number = converter_.toLong(result);

    Validator

    When API JavaScript method is called first thing that has to be done in -JavaScript layer of api implementation is to process and validate arguments +JavaScript layer of API implementation is to process and validate arguments given by the user. The process of validation consists of ensuring that the proper amount of arguments was given and that they were of the expected type and throwing exception if necessary.

    Validator helps to ensure that user sent proper values. Validator is available -at xwalk.utils.validator and predefined js types at xwalk.utils.validator.types

    +at xwalk.utils.validator and predefined JavaScript types at xwalk.utils.validator.types

    Below can be found example of using validator inside setBadgeCount method that requires appId in form of string and long count value:

    var validator_ = xwalk.utils.validator;
    @@ -422,6 +484,9 @@ var args = validator_.validateArgs(arguments, [
       {name: 'count', type: types_.LONG}
     ]);
     
    +

    The validateArgs method may also validate optional and nullable arguments. +See its definition in file src/utils/utils_api.js.

    +

    This method respecting the JavaScript type conversion rules is presented the Appendix A - type conversion tables.

    Exceptions

    At some point whether improper data is received or given to JavaScript might require to throw exceptions. The example below shows how to throw properly @@ -431,6 +496,8 @@ predefined exceptions:

    WebAPIException constructor takes as argument the type of error to be thrown. The second additional argument is error message.

    +

    There might be a need to throw expception because of failure received from C++ layer, +for this case see below section.

    Synchronous methods

    In order to perform synchronous operation (one that does not require callback and the result is given instantly) callSync() method of Native manager needs @@ -450,9 +517,9 @@ Result is assigned to ret variable.

    Asynchronous methods

    In order to work with method that requires callback instead of callSync(), call() method needs to be called. Apart from the first two arguments that are -exactly the same as in call() method (c++ method binding, object) it takes +exactly the same as in callSync() method (C++ method binding, object) it takes additional argument that is a function that will be called when the native -call is processed:

    +call response is processed:

    var native_ = new xwalk.utils.NativeManager(extension);
     var callback = function(result) {
       if (native_.isFailure(result)) {
    @@ -500,6 +567,13 @@ no strict reference between JavaScript and native data.
    Example: If operation should change some object retrieved from platform, identifier should be passed again and additional check if object still exists should be made.

    +

    According to Google C++ Style Guide static variables should NOT be used.

    +

    This rule concerns especially to <pluginname>Manager, <pluginname>Client, +<pluginname>Server etc. classes, which tend to implement the Singleton design pattern. +Because of this, the above mentioned classes' instances should NOT be declared as static +and should NOT be got through getInstance methods. +Instead, the classes's instances should be declared as an private attribute of +<pluginname>Instance class.

    Privileges

    Some of the API methods require privilege access. The privilege engine used in the project is Cynara. In Tizen 3.0 checking if application has privilege to call method has been moved to C++ layer. It's the @@ -572,13 +646,66 @@ if (!result) { ReportSuccess(data, out);

    +

    Dependencies between plugins

    +

    To allow using methods from module A in module B, you need to add dependencies in <pluginname>.gyp files +and add XW_EXPORT macro to the definition of methods in module A.

    +

    In below example, linking GetNotiHandleFromJson method of CommonNotification class in module Notification +is added to the Alarm module.

    +
      +
    1. Add dependency in .gyp file in module B, in this example it is alarm.gyp:
      'dependencies': [
      +'../common/common.gyp:tizen_common',
      +'../notification/notification.gyp:tizen_notification',  # add this line
      +],
      +
    2. +
    3. Add XW_EXPORT macro available in src/common/XW_Extension.h file to the definition of method from module A:
      class UserNotification : public CommonNotification {
      +// ...
      +XW_EXPORT static common::PlatformResult GetNotiHandleFromJson(const picojson::value& noti_val,
      +                                                           bool is_update,
      +                                                           notification_h* noti_handle);
      +// ...
      +}
      +
      +
    4. +
    5. Add dependency in .gyp file in module A, in this example it is notification.gyp:
      {
      +'includes': [
      + '../common/common.gypi',
      +],
      +'targets': [
      + {
      +   'target_name': 'tizen_notification',
      +   'type': 'loadable_module',
      +   'dependencies': [
      +     '../common/common.gyp:tizen_common',
      +   ],
      +   'sources': [
      +     # ...
      +   ],
      +   'conditions': [
      +     # ...
      +   ],
      +   'direct_dependent_settings': {  # add this property
      +     'libraries': [
      +       '-ltizen_notification',
      +     ],
      +   },
      + },
      +],
      +}
      +
    6. +
    +

    To make sure you did the good work, you can list dynamic dependencies of given .so file with the ldd command:

    +
    sh-user-3.2# ldd /usr/lib/tizen-extensions-crosswalk/libtizen_alarm.so | grep noti
    +ldd: warning: you do not have execution permission for `/usr/lib/tizen-extensions-crosswalk/libtizen_alarm.so'
    +libtizen_notification.so => /usr/lib/tizen-extensions-crosswalk/libtizen_notification.so (0xb6e52000)  # OK!
    +libnotification.so.0 => /lib/libnotification.so.0 (0xb6c93000)
    +

    Asynchronous calls

    To perform asynchronous request common::TaskQueue component should be used. You should use lambda expression which calls business logic and passes result to JavaScript layer by calling PostMessage(const char* msg).

    Asynchronous response is not matched to request automatically. You should pass callbackId received from JavaScript layer as an argument. It allows to -call the appropriate user callback in JS async message handler.

    +call the appropriate user callback in JavaScript async message handler.

    auto search = [this, args]() -> void {
     
       // business logic
    @@ -635,8 +762,14 @@ LoggerI("Data size: %d", object->data->size);
     LoggerW("Data in %s object is empty", object->name);
     LoggerE("Error occurred while getting data [%d]", error);
     
    +

    Upon entering and leaving function's scope, a message should be printed with DEBUG priority using ScopeLogger macro:

    +
    // print simply, default "Enter" log
    +ScopeLogger();
    +// print more detailed message
    +ScopeLogger("state: %d; err: %s", (int) state, err);
    +

    Error handling

    -

    Regarding to Google C++ Style Guide we do not use Exceptions.

    +

    Regarding to Google C++ Style Guide we do not use Exceptions.

    To deliver error conditions to JavaScript layer, that can occur in the platform, LogAndReportError or ReportError method should be used. All available error codes are defined in common/platform_result.h

    @@ -828,6 +961,1220 @@ After build and installation webapi-plugins-test webapis.test names
    var test = webapis.test.ping();
     console.log(test); // Hello!
     
    +

    Appendices

    +

    Appendix A - type conversion tables

    +

    Type conversion tables

    +

    Below tables present convertions, which are performed by validateArgs method in +src/utils/utils_api.js file before sending data to C++ layer.

    +
      +
    • Boolean
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefinedfalse
    nullnullfalse
    NumberNaNfalse
    NumberNumber.POSITIVE_INFINITYtrue
    NumberNumber.NEGATIVE_INFINITYtrue
    Number-1true
    Number0false
    Number1true
    Number3.14true
    String"" (Empty String)false
    String"0"true
    String"TIZEN"true
    Object{ name : "TIZEN" }true
    Function Objectfunction () { }true
    +
      +
    • Number : long
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined0
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaN0
    NumberNumber.POSITIVE_INFINITY0
    NumberNumber.NEGATIVE_INFINITY0
    Number-1-1
    Number00
    Number11
    Number3.143
    String"" (Empty String)0
    String"-1"-1
    String"0"0
    String"1"1
    String"3.14"3
    String"TIZEN"0
    Object{ name : "TIZEN" }0
    Function Objectfunction () { }0
    +
      +
    • Number : unsigned long
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined0
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaN0
    NumberNumber.POSITIVE_INFINITY0
    NumberNumber.NEGATIVE_INFINITY0
    Number-14294967295
    Number00
    Number11
    Number3.143
    String"" (Empty String)0
    String"-1"4294967295
    String"0"0
    String"1"1
    String"TIZEN"0
    Object{ name : "TIZEN" }0
    Function Objectfunction () { }0
    +
      +
    • Number : unsigned long long
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined0
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaN0
    NumberNumber.POSITIVE_INFINITY0
    NumberNumber.NEGATIVE_INFINITY0
    Number-118446744073709551615
    Number00
    Number11
    Number3.143
    String"" (Empty String)0
    String"-1"18446744073709551615
    String"0"0
    String"1"1
    String"TIZEN"0
    Object{ name : "TIZEN" }0
    Function Objectfunction () { }0
    +
      +
    • Number : byte [-128, 127]
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined0
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaN0
    NumberNumber.POSITIVE_INFINITY0
    NumberNumber.NEGATIVE_INFINITY0
    Number-1-1
    Number00
    Number11
    Number3.143
    Number-128-128
    Number-19264
    Number-2560
    Number127127
    Number128-128
    Number2560
    String"" (Empty String)0
    String"0"0
    String"1"1
    String"256"0
    String"TIZEN"0
    Object{ name : "TIZEN" }0
    Function Objectfunction () { }0
    +
      +
    • Number : double
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefinedTypeMismatchError
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaNTypeMismatchError
    NumberNumber.POSITIVE_INFINITYTypeMismatchError
    NumberNumber.NEGATIVE_INFINITYTypeMismatchError
    Number-1-1
    Number00
    Number11
    Number3.143.14
    String"" (Empty String)0
    String"0"0
    String"-3.14"-3.14
    String"3.14"3.14
    String"TIZEN"TypeMismatchError
    Object{ name : "TIZEN" }TypeMismatchError
    Function Objectfunction () { }TypeMismatchError
    +
      +
    • String
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined"undefined"
    nullnull"null"
    Booleantrue"true"
    Booleanfalse"false"
    NumberNaN"NaN"
    NumberNumber.POSITIVE_INFINITY"Infinity"
    NumberNumber.NEGATIVE_INFINITY"-Infinity"
    Number-1"-1"
    Number0"0"
    Number1"1"
    Number3.14"3.14"
    Object{ }"[object Object]"
    Function Objectfunction () { }"function () { }"
    +
      +
    • Platform Object
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefinedTypeMismatchError
    nullnullnullable: null; non-nullable: TypeMismatchError
    BooleantrueTypeMismatchError
    BooleanfalseTypeMismatchError
    NumberNaNTypeMismatchError
    Number0TypeMismatchError
    String"TIZEN"TypeMismatchError
    Object{}TypeMismatchError
    Function Objectfunction () { }TypeMismatchError
    +
      +
    • Function Object
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefinedTypeMismatchError
    nullnullnullable: null; non-nullable: TypeMismatchError
    BooleantrueTypeMismatchError
    BooleanfalseTypeMismatchError
    NumberNaNTypeMismatchError
    Number0TypeMismatchError
    String"TIZEN"TypeMismatchError
    Object{ }TypeMismatchError
    +
      +
    • Array Object
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefinedTypeMismatchError
    nullnullnullable: null; non-nullable: TypeMismatchError
    BooleantrueTypeMismatchError
    BooleanfalseTypeMismatchError
    NumberNaNTypeMismatchError
    Number0TypeMismatchError
    String"TIZEN"TypeMismatchError
    Object{ }TypeMismatchError
    Function Objectfunction () { }TypeMismatchError
    +
      +
    • Dictionary
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResultComment
    undefinedundefinedTypeMismatchError
    nullnullnullable: null; non-nullable: TypeMismatchError
    BooleantrueTypeMismatchError
    BooleanfalseTypeMismatchError
    NumberNaNTypeMismatchError
    Number0TypeMismatchError
    String"TIZEN"TypeMismatchError
    Object{ }{}No exception is thrown
    Function Objectfunction () { }function () { }No exception is thrown
    +
      +
    • Octet [0, 255]
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResult
    undefinedundefined0
    nullnull0
    Booleantrue1
    Booleanfalse0
    NumberNaN0
    NumberNumber.POSITIVE_INFINITY0
    NumberNumber.NEGATIVE_INFINITY0
    Number-1255
    Number00
    Number11
    Number3.143
    Number-128128
    Number-19264
    Number-2560
    Number2560
    String"" (Empty String)0
    String"0"0
    String"1"1
    String"256"0
    String"TIZEN"0
    Object{ name : "TIZEN" }0
    Function Objectfunction () { }0
    +
      +
    • Enum
    • +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Input TypeInput ValueResultComment
    undefinedundefinedTypeMismatchErrorunless "undefined" is on the list of the Enum values
    nullnullTypeMismatchErrorunless "null" is one of the Enum values
    Number0TypeMismatchErrorunless "0" is one of the Enum values
    BooleantrueTypeMismatchErrorunless "true" is one of the Enum values
    String"TIZEN"TypeMismatchErrorunless "TIZEN" is one of the Enum values
    Stringany of the Enum valuesgiven stringEnum defines valid values, any of those values can be used and are accepted without conversion
    Object{ }TypeMismatchError
    +

    Appendix B - Javascript code example style guide

    +

    Code Example Style Guide

    +

    Below guide lists rules of writing example code placed in the WIDL files.

    +

    Whitespaces

    +
      +
    • Use only spaces (do not use tabs), one level indent has two spaces
    • +
    • No whitespace at the end of line
    • +
    • One extra space after keywords which use round brackets (if, for, while, switch, catch, …)
    • +
    • Add space between variables and operators
    • +
    • Initialization lists
        +
      • Space after colon but not before
      • +
      • Space after comma
      • +
      +
    • +
    +

    Comments

    +
      +
    • Use double slash // (do not use / /)
    • +
    • Start sentence with capital letter
    • +
    • Do not use dot at the end
    • +
    +
    // This is a simple comment
    +
    +

    Brackets

    +
      +
    • Body brackets
        +
      • Opening and closing brackets in new lines
      • +
      +
    • +
    • No extra whitespace inside brackets (after opening nor before closing)
    • +
    +
    try
    +{
    +  var messages = ["A", "B"];
    +}
    +catch (err)
    +{
    +  console.log("Error: " + err.message);
    +}
    +
    +

    Strings

    +
      +
    • Use only quotation marks (“), do not use apostrophes (‘) to create strings
    • +
    +

    console.log()

    +
      +
    • Start log with capital letter
    • +
    • Do not use dots
    • +
    • Add space after colon
    • +
    +
    console.log(“This is example error: “ + err.message);
    +
    +

    Multi-line

    +
      +
    • Each line should not be more than 100 characters long
    • +
    • Indentation in second line must match opening bracket
    • +
    +
    console.log("This is console log information error: " + error.message +
    +            " and there is more”);
    +
    +

    Functions with function as an argument

    +
      +
    • Name of the function should be written in line with previous function's closing bracket
    • +
    • Other parameters can be put in the same line as function's closing bracket
    • +
    +
    functionCalculate("First argument", function(e)
    +{
    +  console.log("Information: " + e.message);
    +}, function(e)
    +{
    +  console.log("Error: " + e.message);
    +}, "Last argument");
    +
    +

    Statement separation

    +
      +
    • Each statement has to be in new line and has to end with semicolon
    • +
    diff --git a/doc/package.json b/doc/package.json index 2a7a0694..7ead273d 100644 --- a/doc/package.json +++ b/doc/package.json @@ -1,6 +1,6 @@ { "name": "WebApiGuidelines", - "version": "0.3.0", + "version": "0.7.0", "dependencies": { "doctor-md": "git://github.com/Hagith/doctor.git#print-css" }, diff --git a/doc/src/appendices.md b/doc/src/appendices.md new file mode 100644 index 00000000..c4ab246d --- /dev/null +++ b/doc/src/appendices.md @@ -0,0 +1 @@ +## Appendices diff --git a/doc/src/appendix_a.md b/doc/src/appendix_a.md new file mode 100644 index 00000000..fea5a18e --- /dev/null +++ b/doc/src/appendix_a.md @@ -0,0 +1,259 @@ +### Appendix A - type conversion tables + +#### Type conversion tables + +Below tables present convertions, which are performed by ``validateArgs`` method in +``src/utils/utils_api.js`` file before sending data to C++ layer. + +* Boolean + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|false| +|null|null|false| +|Number|NaN|false| +|Number|Number.POSITIVE_INFINITY|true| +|Number|Number.NEGATIVE_INFINITY|true| +|Number|-1|true| +|Number|0|false| +|Number|1|true| +|Number|3.14|true| +|String|"" (Empty String)|false| +|String|"0"|true| +|String|"TIZEN"|true| +|Object|{ name : "TIZEN" }|true| +|Function Object|function () { }|true| + +* Number : long + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|0| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|0| +|Number|Number.POSITIVE_INFINITY|0| +|Number|Number.NEGATIVE_INFINITY|0| +|Number|-1|-1| +|Number|0|0| +|Number|1|1| +|Number|3.14|3| +|String|"" (Empty String)|0| +|String|"-1"|-1| +|String|"0"|0| +|String|"1"|1| +|String|"3.14"|3| +|String|"TIZEN"|0| +|Object|{ name : "TIZEN" }|0| +|Function Object|function () { }|0| + +* Number : unsigned long + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|0| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|0| +|Number|Number.POSITIVE_INFINITY|0| +|Number|Number.NEGATIVE_INFINITY|0| +|Number|-1|4294967295| +|Number|0|0| +|Number|1|1| +|Number|3.14|3| +|String|"" (Empty String)|0| +|String|"-1"|4294967295| +|String|"0"|0| +|String|"1"|1| +|String|"TIZEN"|0| +|Object|{ name : "TIZEN" }|0| +|Function Object|function () { }|0| + +* Number : unsigned long long + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|0| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|0| +|Number|Number.POSITIVE_INFINITY|0| +|Number|Number.NEGATIVE_INFINITY|0| +|Number|-1|18446744073709551615| +|Number|0|0| +|Number|1|1| +|Number|3.14|3| +|String|"" (Empty String)|0| +|String|"-1"|18446744073709551615| +|String|"0"|0| +|String|"1"|1| +|String|"TIZEN"|0| +|Object|{ name : "TIZEN" }|0| +|Function Object|function () { }|0| + +* Number : byte [-128, 127] + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|0| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|0| +|Number|Number.POSITIVE_INFINITY|0| +|Number|Number.NEGATIVE_INFINITY|0| +|Number|-1|-1| +|Number|0|0| +|Number|1|1| +|Number|3.14|3| +|Number|-128|-128| +|Number|-192|64| +|Number|-256|0| +|Number|127|127| +|Number|128|-128| +|Number|256|0| +|String|"" (Empty String)|0| +|String|"0"|0| +|String|"1"|1| +|String|"256"|0| +|String|"TIZEN"|0| +|Object|{ name : "TIZEN" }|0| +|Function Object|function () { }|0| + +* Number : double + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|TypeMismatchError| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|TypeMismatchError| +|Number|Number.POSITIVE_INFINITY|TypeMismatchError| +|Number|Number.NEGATIVE_INFINITY|TypeMismatchError| +|Number|-1|-1| +|Number|0|0| +|Number|1|1| +|Number|3.14|3.14| +|String|"" (Empty String)|0| +|String|"0"|0| +|String|"-3.14"|-3.14| +|String|"3.14"|3.14| +|String|"TIZEN"|TypeMismatchError| +|Object|{ name : "TIZEN" }|TypeMismatchError| +|Function Object|function () { }|TypeMismatchError| + +* String + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|"undefined"| +|null|null|"null"| +|Boolean|true|"true"| +|Boolean|false|"false"| +|Number|NaN|"NaN"| +|Number|Number.POSITIVE_INFINITY|"Infinity"| +|Number|Number.NEGATIVE_INFINITY|"-Infinity"| +|Number|-1|"-1"| +|Number|0|"0"| +|Number|1|"1"| +|Number|3.14|"3.14"| +|Object|{ }|"[object Object]"| +|Function Object|function () { }|"function () { }"| + +* Platform Object + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|TypeMismatchError| +|null|null|nullable: null; non-nullable: TypeMismatchError| +|Boolean|true|TypeMismatchError| +|Boolean|false|TypeMismatchError| +|Number|NaN|TypeMismatchError| +|Number|0|TypeMismatchError| +|String|"TIZEN"|TypeMismatchError| +|Object|{}|TypeMismatchError| +|Function Object|function () { }|TypeMismatchError| + +* Function Object + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|TypeMismatchError| +|null|null|nullable: null; non-nullable: TypeMismatchError| +|Boolean|true|TypeMismatchError| +|Boolean|false|TypeMismatchError| +|Number|NaN|TypeMismatchError| +|Number|0|TypeMismatchError| +|String|"TIZEN"|TypeMismatchError| +|Object|{ }|TypeMismatchError| + +* Array Object + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|TypeMismatchError| +|null|null|nullable: null; non-nullable: TypeMismatchError| +|Boolean|true|TypeMismatchError| +|Boolean|false|TypeMismatchError| +|Number|NaN|TypeMismatchError| +|Number|0|TypeMismatchError| +|String|"TIZEN"|TypeMismatchError| +|Object|{ }|TypeMismatchError| +|Function Object|function () { }|TypeMismatchError| + +* Dictionary + +|Input Type|Input Value|Result|Comment| +|----------|-----------|------|-------| +|undefined|undefined|TypeMismatchError| +|null|null|nullable: null; non-nullable: TypeMismatchError| +|Boolean|true|TypeMismatchError| +|Boolean|false|TypeMismatchError| +|Number|NaN|TypeMismatchError| +|Number|0|TypeMismatchError| +|String|"TIZEN"|TypeMismatchError| +|Object|{ }|{}|No exception is thrown +|Function Object|function () { }|function () { }|No exception is thrown + +* Octet [0, 255] + +|Input Type|Input Value|Result| +|----------|-----------|------| +|undefined|undefined|0| +|null|null|0| +|Boolean|true|1| +|Boolean|false|0| +|Number|NaN|0| +|Number|Number.POSITIVE_INFINITY|0| +|Number|Number.NEGATIVE_INFINITY|0| +|Number|-1|255| +|Number|0|0| +|Number|1|1| +|Number|3.14|3| +|Number|-128|128| +|Number|-192|64| +|Number|-256|0| +|Number|256|0| +|String|"" (Empty String)|0| +|String|"0"|0| +|String|"1"|1| +|String|"256"|0| +|String|"TIZEN"|0| +|Object|{ name : "TIZEN" }|0| +|Function Object|function () { }|0| + +* Enum + +|Input Type|Input Value|Result|Comment| +|----------|-----------|------|-------| +|undefined|undefined|TypeMismatchError|unless "undefined" is on the list of the Enum values +|null|null|TypeMismatchError|unless "null" is one of the Enum values +|Number|0|TypeMismatchError|unless "0" is one of the Enum values +|Boolean|true|TypeMismatchError|unless "true" is one of the Enum values +|String|"TIZEN"|TypeMismatchError|unless "TIZEN" is one of the Enum values +|String|any of the Enum values|given string|Enum defines valid values, any of those values can be used and are accepted without conversion +|Object|{ }|TypeMismatchError| diff --git a/doc/src/appendix_b.md b/doc/src/appendix_b.md new file mode 100644 index 00000000..b725a8d9 --- /dev/null +++ b/doc/src/appendix_b.md @@ -0,0 +1,85 @@ +### Appendix B - Javascript code example style guide + +#### Code Example Style Guide + +Below guide lists rules of writing example code placed in the WIDL files. + +**Whitespaces** + +- Use only spaces (do not use tabs), one level indent has two spaces +- No whitespace at the end of line +- One extra space after keywords which use round brackets (if, for, while, switch, catch, …) +- Add space between variables and operators +- Initialization lists + - Space after colon but not before + - Space after comma + +**Comments** + +- Use double slash // (do not use /* */) +- Start sentence with capital letter +- Do not use dot at the end + +```js +// This is a simple comment +``` + +**Brackets** + +- Body brackets + - Opening and closing brackets in new lines +- No extra whitespace inside brackets (after opening nor before closing) + +```js +try +{ + var messages = ["A", "B"]; +} +catch (err) +{ + console.log("Error: " + err.message); +} +``` + +**Strings** + +- Use only quotation marks (“), do not use apostrophes (‘) to create strings + +**console.log()** + +- Start log with capital letter +- Do not use dots +- Add space after colon + +```js +console.log(“This is example error: “ + err.message); +``` + +**Multi-line** + +- Each line should not be more than 100 characters long +- Indentation in second line must match opening bracket + +```js +console.log("This is console log information error: " + error.message + + " and there is more”); +``` + +**Functions with function as an argument** + +- Name of the function should be written in line with previous function's closing bracket +- Other parameters can be put in the same line as function's closing bracket + +```js +functionCalculate("First argument", function(e) +{ + console.log("Information: " + e.message); +}, function(e) +{ + console.log("Error: " + e.message); +}, "Last argument"); +``` + +**Statement separation** + +- Each statement has to be in new line and has to end with semicolon \ No newline at end of file diff --git a/doc/src/guideline.md b/doc/src/guideline.md index 4e39a93f..78fc78b8 100644 --- a/doc/src/guideline.md +++ b/doc/src/guideline.md @@ -6,10 +6,15 @@ C++, JavaScript ### Coding style -Use Google style guide, -C++: http://google-styleguide.googlecode.com/svn/trunk/cppguide.html +Use Google style guides (with small exceptions): -JavaScript: http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml +C++: https://google.github.io/styleguide/cppguide.html + +JavaScript: https://google.github.io/styleguide/jsguide.html + +On branches ```tizen_3.0``` and higher, the C++ ~~and JavaScript~~ files are formatted using scripts, +which its usage is described in the [Format code](#tools/format-code) section of this document. +The section also describes where the exceptions from Google coding style are defined. ### API guide @@ -29,11 +34,11 @@ $ git clone ssh://@168.219.209.56:29418/framework/web/webapi-plugins $ cd webapi-plugins $ git checkout origin/tizen_2.4 ``` -For Tizen 3.0 +For Tizen 3.0 and higher ```sh -$ git clone ssh://@168.219.209.56:29418/framework/web/webapi-plugins +$ git clone ssh://@review.tizen.org:29418/platform/core/api/webapi-plugins && scp -p -P 29418 @review.tizen.org:hooks/commit-msg webapi-plugins/.git/hooks/ $ cd webapi-plugins -$ git checkout origin/tizen_3.0 +$ git checkout origin/tizen_ ``` ### License and Boilerplate @@ -41,7 +46,7 @@ $ git checkout origin/tizen_3.0 Use this boilerplate in every new created source files. ```sh /* - * Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved + * Copyright (c) Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/doc/src/implementation_cc.md b/doc/src/implementation_cc.md index c6d84e51..7ea4fdd9 100644 --- a/doc/src/implementation_cc.md +++ b/doc/src/implementation_cc.md @@ -18,6 +18,15 @@ Example: If operation should change some object retrieved from platform, identifier should be passed again and additional check if object still exists should be made. +According to [Google C++ Style Guide][3] static variables should **NOT** be used. + +This rule concerns especially to ```Manager```, ```Client```, +```Server``` etc. classes, which tend to implement the Singleton design pattern. +Because of this, the above mentioned classes' instances should **NOT** be declared as ``static`` +and should **NOT** be got through ``getInstance`` methods. +Instead, the classes's instances should be declared as an ``private`` attribute of +```Instance``` class. + ### Privileges Some of the API methods require privilege access. The privilege engine used in the project is Cynara. @@ -110,6 +119,68 @@ if (!result) { ReportSuccess(data, out); ``` +### Dependencies between plugins + +To allow using methods from module ``A`` in module ``B``, you need to add dependencies in ``.gyp`` files +and add ``XW_EXPORT`` macro to the definition of methods in module ``A``. + +In below example, linking ``GetNotiHandleFromJson`` method of ``CommonNotification`` class in module ``Notification`` +is added to the ``Alarm`` module. + +1. Add dependency in ``.gyp`` file in module ``B``, in this example it is ``alarm.gyp``: +``` +'dependencies': [ + '../common/common.gyp:tizen_common', + '../notification/notification.gyp:tizen_notification', # add this line +], +``` +2. Add ``XW_EXPORT`` macro available in ``src/common/XW_Extension.h`` file to the definition of method from module ``A``: +```cpp +class UserNotification : public CommonNotification { +// ... +XW_EXPORT static common::PlatformResult GetNotiHandleFromJson(const picojson::value& noti_val, + bool is_update, + notification_h* noti_handle); +// ... +} +``` +3. Add dependency in ``.gyp`` file in module ``A``, in this example it is ``notification.gyp``: +``` +{ + 'includes': [ + '../common/common.gypi', + ], + 'targets': [ + { + 'target_name': 'tizen_notification', + 'type': 'loadable_module', + 'dependencies': [ + '../common/common.gyp:tizen_common', + ], + 'sources': [ + # ... + ], + 'conditions': [ + # ... + ], + 'direct_dependent_settings': { # add this property + 'libraries': [ + '-ltizen_notification', + ], + }, + }, + ], +} +``` + +To make sure you did the good work, you can list dynamic dependencies of given ``.so`` file with the ``ldd`` command: +```sh +sh-user-3.2# ldd /usr/lib/tizen-extensions-crosswalk/libtizen_alarm.so | grep noti +ldd: warning: you do not have execution permission for `/usr/lib/tizen-extensions-crosswalk/libtizen_alarm.so' +libtizen_notification.so => /usr/lib/tizen-extensions-crosswalk/libtizen_notification.so (0xb6e52000) # OK! +libnotification.so.0 => /lib/libnotification.so.0 (0xb6c93000) +``` + ### Asynchronous calls To perform asynchronous request ```common::TaskQueue``` component should be used. @@ -118,7 +189,7 @@ JavaScript layer by calling ```PostMessage(const char* msg)```. Asynchronous response is not matched to request automatically. You should pass ```callbackId``` received from JavaScript layer as an argument. It allows to -call the appropriate user callback in JS async message handler. +call the appropriate user callback in JavaScript async message handler. ```cpp auto search = [this, args]() -> void { @@ -184,6 +255,16 @@ LoggerW("Data in %s object is empty", object->name); LoggerE("Error occurred while getting data [%d]", error); ``` +Upon entering and leaving function's scope, a message should be printed with ```DEBUG``` priority using ``ScopeLogger`` macro: + +```cpp +// print simply, default "Enter" log +ScopeLogger(); +// print more detailed message +ScopeLogger("state: %d; err: %s", (int) state, err); +``` + + ### Error handling Regarding to [Google C++ Style Guide][2] we do not use Exceptions. @@ -210,4 +291,5 @@ if (native_.isFailure(ret)) { ``` [1]: http://en.wikipedia.org/wiki/SOLID_(object-oriented_design) - [2]: http://google-styleguide.googlecode.com/svn/trunk/cppguide.html#Exceptions + [2]: https://google.github.io/styleguide/cppguide.html#Exceptions + [3]: https://google.github.io/styleguide/cppguide.html#Static_and_Global_Variables diff --git a/doc/src/implementation_js.md b/doc/src/implementation_js.md index 569060d7..4e7ca432 100644 --- a/doc/src/implementation_js.md +++ b/doc/src/implementation_js.md @@ -1,10 +1,9 @@ ## Implementation - JavaScript Each plugin contains JavaScript files. This is the place where user input is -being processed validated before send to C++ layer. +being processed validated before sending to C++ layer. -Badge API will be used to show the creation of JavaScript file (lot of content -of this file will be already generated via Stub Generator). +Badge API will be used to show the creation of JavaScript file. ### Interface creation @@ -89,13 +88,13 @@ var number = converter_.toLong(result); #### Validator When API JavaScript method is called first thing that has to be done in -JavaScript layer of api implementation is to process and validate arguments +JavaScript layer of API implementation is to process and validate arguments given by the user. The process of validation consists of ensuring that the proper amount of arguments was given and that they were of the expected type and throwing exception if necessary. Validator helps to ensure that user sent proper values. Validator is available -at ```xwalk.utils.validator``` and predefined js types at ```xwalk.utils.validator.types``` +at ```xwalk.utils.validator``` and predefined JavaScript types at ```xwalk.utils.validator.types``` Below can be found example of using validator inside ```setBadgeCount``` method that requires appId in form of string and long count value: @@ -110,6 +109,11 @@ var args = validator_.validateArgs(arguments, [ ]); ``` +The ``validateArgs`` method may also validate optional and nullable arguments. +See its definition in file ``src/utils/utils_api.js``. + +This method respecting the JavaScript type conversion rules is presented [the Appendix A - type conversion tables](#appendices/appendix-a-type-conversion-tables). + ### Exceptions At some point whether improper data is received or given to JavaScript might @@ -124,6 +128,9 @@ throw new WebAPIException(WebAPIException.TYPE_MISMATCH_ERR, WebAPIException constructor takes as argument the type of error to be thrown. The second additional argument is error message. +There might be a need to throw expception because of failure received from C++ layer, +for this case see below section. + ### Synchronous methods In order to perform synchronous operation (one that does not require callback @@ -149,9 +156,9 @@ Result is assigned to ret variable. In order to work with method that requires callback instead of callSync(), call() method needs to be called. Apart from the first two arguments that are -exactly the same as in call() method (c++ method binding, object) it takes +exactly the same as in callSync() method (C++ method binding, object) it takes additional argument that is a function that will be called when the native -call is processed: +call response is processed: ```js var native_ = new xwalk.utils.NativeManager(extension); diff --git a/doc/src/index.md b/doc/src/index.md index 12d50f4f..84bd52ad 100644 --- a/doc/src/index.md +++ b/doc/src/index.md @@ -11,6 +11,7 @@ | 0.5.0 | 2015-06-18 | Devel package | Pawel Kaczmarek
    | | 0.5.1 | 2015-06-24 | Add info about WAPIOven.py | Pawel Kaczmarek
    | | 0.6.0 | 2016-10-28 | update devel package for tizen 3.0 | Annie Park
    | +| 0.7.0 | 2017-11-09 | Update guidelines for Tizen 4.0 | Szymon Jastrzębski
    | ## Overview This document should be used as a guideline for developers who are creating web @@ -25,3 +26,6 @@ Each plugin should be written with great attention on JavaScript. {{>src/implementation_js.md}} {{>src/implementation_cc.md}} {{>src/devel_package.md}} +{{>src/appendices.md}} +{{>src/appendix_a.md}} +{{>src/appendix_b.md}} \ No newline at end of file diff --git a/doc/src/plugin_structure.md b/doc/src/plugin_structure.md index 161b0d4a..ac1dccea 100644 --- a/doc/src/plugin_structure.md +++ b/doc/src/plugin_structure.md @@ -14,16 +14,29 @@ Each plugin contains following structure: * ```_instance.h``` * ```_instance.cc``` +Additionally, plugins may contain below structure, depending on the WIDL specification file: +* ```_client.h``` +* ```_client.cc``` +* ```_server.h``` +* ```_server.cc``` +* ```_service.h``` +* ```_service.cc``` +* ```_util.h``` +* ```_util.cc``` + +and other files with similar naming-convention needed by the developer. + + ### Spec file Spec file (```webapi-plugins.spec```) kept inside ```packaging/``` directory -is build specification file used by RPM packaging system where variables are defined. +is a build specification file used by RPM packaging system where variables are defined. Those variables can be used to include or exclude particular modules from build for each profile (mobile, TV, wearable). ### Manifest file -Each RPM package must have a manifest file where developers can specify the access control domain +Each RPM package must have a manifest file, where developers can specify the access control domain in which their application should be running and potentially additional security policies for the application. It is necessary to build the project. The manifest file (```webapi-plugins.manifest```) is located in the root directory of the project. @@ -47,7 +60,7 @@ Description of files required in plugin implementation. This file contains all methods required by each API. All operation should be done by JavaScript as much as possible. If JavaScript can do something, it should do it. - This file is responsible for checking arguments, calling C++ methods etc. + This file is responsible for checking and validating arguments, calling C++ methods etc. ### Plugin flow @@ -58,7 +71,30 @@ Explanation of steps: This information consists of type of call (asynchronous, synchronous) arguments given by user, any additional information that is required to successfully acquire required data. Data is sent in form of JSON. -2. C++ parses acquired JSON. After the data is processed. Appropriate platform +2. C++ parses acquired JSON. After the data is processed, appropriate platform functions are called with the specified arguments. 3. Platform returns specified values to C++ layer. 4. Another JSON is formed. It consists of data that was acquired from platform. + The data is sent to JavaScript layer. + +### Tizen Unified + +With Tizen 4.0 an idea of Tizen Unified was introduced. + +Before Tizen 4.0, each profile specified in ``.gbs.conf`` file defined the package repositories +for a single device type and a particular architecture. + +Since Tizen 4.0, each GBS profile is associated with a particular architecture and all device types. + +Each device with given profile and architecture requires to have at least 2 RPM files installed: +```sh +webapi-plugins-x.y-z.ARCH.rpm +webapi-plugins-profile_PROFILE_NAME-x.y-z.ARCH.rpm +``` + +However, emulators require to have 3 RPM files installed: +```sh +webapi-plugins-x.y-z.i686.rpm +webapi-plugins-profile_PROFILE_NAME-x.y-z.i686.rpm +webapi-plugins-PROFILE_NAME-extension-emulator-x.y-z.i686.rpm +``` diff --git a/doc/src/tools.md b/doc/src/tools.md index 1836f6e4..2ceb3b7a 100644 --- a/doc/src/tools.md +++ b/doc/src/tools.md @@ -2,6 +2,8 @@ ### Generate stub code +#### **The generator is no longer maintained.** + To generate stub files from the widl you can use stub generator located in ```tools/skeleton_generator/``` directory and run the python command: @@ -36,7 +38,7 @@ WIDL files can be found in the project repository: $ git clone ssh://@168.219.209.56:29418/doc/web-device-api ``` -The widl files are placed in: ```web-device-api/web/widl/tizen/``` +The widl files are placed in: ```web-device-api/web/widl/tizen/``` directory. Stub files generated by above command: @@ -72,3 +74,38 @@ Inside ```_api.js``` required JavaScript files should be added: To merge all JavaScript files ```tools/mergejs.py``` file is used. This script merge all files mentioned in ```_api.js``` file into one file before build process. + + +### Format code + +To format code use scripts provided in the ``tools/codestyle`` directory. + +``cpplint`` is used to validate C++ and ``eslint`` for JavaScript files. + +**Currently, the JavaScript validator and formatter seems to be a little buggy, +thus it is not recommended to use.** + +The developer needs to have ``python``, ``node.js``, ``eslint``, ``Closure Linter`` and ``clang-format`` installed. + +It is worth to make life easier by creating symbolic link to ``clang-format``. +```sh +sudo ln -s /usr/bin/clang-format- /usr/bin/clang-format +``` + +For convenience, in the root of the project links were provided for easier access: +- ``code_format -> tools/codestyle/code_formatter.sh`` +- ``code_validate -> tools/codestyle/code_validation.sh`` + +Those scripts consist of configuration for rules regarding the Google style guides, with few exceptions. + +To format and validate C++ and JavaScript code run in the root of the project: +```sh +./code_validate -a # -a for all, -c for C++, -js for JavaScript files +./code_format -a # use -h or --help for help +``` +The scripts also accept a path to module's directory. +By default every directory module in the ``src`` directory is used. + +For more details, please see ``tools/codestyle/README`` file. + +This rule concerns to branches ``tizen_3.0`` and above. diff --git a/doc/src/widl.md b/doc/src/widl.md index 703958f4..fb8166c2 100644 --- a/doc/src/widl.md +++ b/doc/src/widl.md @@ -39,7 +39,7 @@ In interface definition you can put following members: can be changed, if it is not read only. * Operation: Interface member, which represents method inside object. It is a function of programming language, which can be executed and returns a result. -* Special operation: Performs a specific task. i.e. deleter, getter +* Special operation: Performs a specific task. i.e. deleter, getter. * Static operation: It is not called for a specific instance of the interface, is called for static object regardless of an instance creation. It is connected with the interface itself. @@ -72,8 +72,8 @@ Tizen implements ManagerObject To provide actual implementations of ManagerObject, instance of its Manager interface definition has to be made. Inside this Manager interface all attributes -and functions that will be available form manager namespace, should be defined. -There can be attributes which are other interfaces, operations and everything +and functions that will be available from manager namespace, should be defined. +There can be attributes, which are other interfaces, operations and everything that interfaces allows. Additional interface can be available as a standalone types not connected to @@ -118,6 +118,11 @@ lacks of keyword ```FunctionOnly```. }; ``` +### Example code style + +Coding style for example codes put in the between ``\code`` and ``\endcode`` tags +should be written with respect to rules described in [the Appendix B](#appendices/appendix-b-javascript-code-example-style-guide). + ### Example Example of WIDL file: