提交 95816a4d 编写于 作者: W wenjun

update docs

上级 38b9c760
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
\ No newline at end of file
......@@ -666,34 +666,6 @@ int Foo(const char * restrict p); // OK.
### <a name="r2-12"></a>规则2.12 编译预处理的"#"默认放在行首,嵌套编译预处理语句时,"#"可以进行缩进
编译预处理的"#"统一放在行首;即便编译预处理的代码是嵌入在函数体中的,"#"也应该放在行首。
```c
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) // Good:"#"放在行首
#define ATOMIC_X86_HAS_CMPXCHG16B 1 // Good:"#"放在行首
#else
#define ATOMIC_X86_HAS_CMPXCHG16B 0
#endif
int FunctionName(void)
{
if (someThingError) {
...
#ifdef HAS_SYSLOG // Good:即便在函数内部,"#"也放在行首
WriteToSysLog();
#else
WriteToFileLog();
#endif
}
}
```
嵌套的预处理语句"#"可以按照缩进要求进行缩进对齐,区分层次。
```c
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define ATOMIC_X86_HAS_CMPXCHG16B 1 // Good:区分层次,便于阅读
#else
#define ATOMIC_X86_HAS_CMPXCHG16B 0
#endif
```
## <a name="c2-14"></a>空格和空行
......@@ -850,7 +822,7 @@ int Foo(void)
### <a name="r3-1"></a>规则3.1 文件头注释必须包含版权许可
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Copyright (c) 2020 XXX
* 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
......@@ -979,19 +951,10 @@ int bar = 200; /* 放右边的注释 */
这里说的注释掉代码,包括用 /\* \*/ 和 //,还包括 #if 0, #ifdef NEVER_DEFINED 等等。
### <a name="a3-1"></a>建议3.1 正式交付的代码不能包含 TODO/TBD/FIXME 注释
TODO/TBD 注释一般用来描述已知待改进、待补充的修改点
FIXME 注释一般用来描述已知缺陷
它们都应该有统一风格,方便文本搜索统一处理。如:
```c
// TODO(<author-name>): 补充XX处理
// FIXME: XX缺陷
```
在版本开发阶段,可以使用此类注释用于突出标注;交付前应该全部处理并删除掉。
### <a name="a3-2"></a>建议3.2 case语句块结束时如果不加break/return,需要有注释说明(fall-through)
### <a name="a3-1"></a>建议3.1 case语句块结束时如果不加break/return,需要有注释说明(fall-through)
有时候需要对多个case标签做相同的事情,case语句在结束不加break或return,直接执行下一个case标签中的语句,这在C语法中称之为"fall-through"。
这种情况下,需要在"fall-through"的地方加上注释,清晰明确的表达出这样做的意图;或者至少显式指明是 "fall-through"。
......@@ -1470,7 +1433,7 @@ int OtherFunc(void)
#define ASSERT(x) do { \
if (!(x)) { \
printk(KERN_EMERG "assertion failed %s: %d: %s\n", \
__FILE__, __LINE__, #x); \
__FILE__, __LINE__, #x); \
BUG(); \
} \
} while (0)
......
......@@ -38,7 +38,7 @@
## <a name="c2-1"></a>通用命名
__驼峰风格(CamelCase)__
大小写字母混用,单词连在一起,不同单词间通过单词首字母大写来分开。
按连接后的首字母是否大写,又分: 大驼峰(UperCamelCase)和小驼峰(lowerCamelCase)
按连接后的首字母是否大写,又分: 大驼峰(UpperCamelCase)和小驼峰(lowerCamelCase)
| 类型 | 命名风格 |
......@@ -60,7 +60,7 @@ __驼峰风格(CamelCase)__
目前业界还有一些其他的后缀的表示方法:
- 头文件: .hh, .hpp, .hxx
- cpp文件:.cc, .cxx, .C
- cpp文件:.cc, .cxx, .c
如果当前项目组使用了某种特定的后缀,那么可以继续使用,但是请保持风格统一。
但是对于本文档,我们默认使用.h和.cpp作为后缀。
......@@ -416,7 +416,7 @@ default: // Bad: default 未缩进
// 假设下面第一行已经不满足行宽要求
```cpp
if (currentValue > threshold && // Good:换行后,逻辑操作符放在行尾
if ((currentValue > threshold) && // Good:换行后,逻辑操作符放在行尾
someConditionsion) {
DoSomething();
...
......@@ -475,11 +475,11 @@ const int rank[] = {
### <a name="a3-12-1"></a>建议3.12.1 指针类型"`*`"跟随变量名或者类型,不要两边都留有或者都没有空格
指针命名: `*`靠左靠右都可以,但是不要两边都有或者都没有空格。
```cpp
int* p = NULL; // Good
int *p = NULL; // Good
int* p = nullptr; // Good
int *p = nullptr; // Good
int*p = NULL; // Bad
int * p = NULL; // Bad
int*p = nullptr; // Bad
int * p = nullptr; // Bad
```
例外:当变量被 const 修饰时,"`*`" 无法跟随变量,此时也不要跟随类型。
......@@ -506,35 +506,6 @@ int&p = i; // Bad
### <a name="r3-13-1"></a>规则3.13.1 编译预处理的"#"统一放在行首,嵌套编译预处理语句时,"#"可以进行缩进
编译预处理的"#"统一放在行首,即使编译预处理的代码是嵌入在函数体中的,"#"也应该放在行首。
```cpp
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16) // Good:"#"放在行首
#define ATOMIC_X86_HAS_CMPXCHG16B 1 // Good:"#"放在行首
#else
#define ATOMIC_X86_HAS_CMPXCHG16B 0
#endif
int FunctionName()
{
if (someThingError) {
...
#ifdef HAS_SYSLOG // Good:即便在函数内部,"#"也放在行首
WriteToSysLog();
#else
WriteToFileLog();
#endif
}
}
```
内嵌的预处理语句"#"可以按照缩进要求进行缩进对齐,区分层次。
```cpp
#if defined(__x86_64__) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define ATOMIC_X86_HAS_CMPXCHG16B 1 // Good:区分层次,便于阅读
#else
#define ATOMIC_X86_HAS_CMPXCHG16B 0
#endif
```
## <a name="c3-14"></a> 空格和空行
### <a name="r3-14-1"></a>规则3.14.1 水平空格应该突出关键字和重要信息,避免不必要的留白
......@@ -794,7 +765,7 @@ MyClass::MyClass(int var)
### <a name="r3-1"></a>规则3.1 文件头注释必须包含版权许可
/*
* Copyright (c) 2020 Huawei Device Co., Ltd.
* Copyright (c) 2020 XXX
* 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
......@@ -925,17 +896,6 @@ const int ANOTHER_CONST = 200; /* 上下对齐时,与左侧代码保持间
这里说的注释掉代码,包括用 /* */ 和 //,还包括 #if 0, #ifdef NEVER_DEFINED 等等。
### <a name="a4-4-1"></a>建议4.4.1 正式交付给客户的代码不能包含 TODO/TBD/FIXME 注释
TODO/TBD 注释一般用来描述已知待改进、待补充的修改点
FIXME 注释一般用来描述已知缺陷
它们都应该有统一风格,方便文本搜索统一处理。如:
```cpp
// TODO(<author-name>): 补充XX处理
// FIXME: XX缺陷
```
# <a name="c5"></a>5 头文件
## <a name="c5-1"></a> 头文件职责
头文件是模块或文件的对外接口,头文件的设计体现了大部分的系统设计。
......@@ -1145,7 +1105,7 @@ extern "C" {
namespace {
const int MAX_COUNT = 20;
void InternalFun(){};
void InternalFun() {};
}
void Foo::Fun()
......@@ -1339,7 +1299,7 @@ message.ProcessOutMsg(); // 后续使用存在隐患
// 因此,有必要定义默认构造函数,如下:
class Message {
public:
Message() : msgID_(0), msgLength_(0), msgBuffer_(NULL)
Message() : msgID_(0), msgLength_(0), msgBuffer_(nullptr)
{
}
......@@ -1364,7 +1324,7 @@ class Message {
public:
Message() : msgLength_(0) // Good,优先使用初始化列表
{
msgBuffer_ = NULL; // Bad,不推荐在构造函数中赋值
msgBuffer_ = nullptr; // Bad,不推荐在构造函数中赋值
}
private:
......@@ -1448,7 +1408,7 @@ private:
### <a name="r7-1-5"></a>规则7.1.5 移动构造和移动赋值操作符应该是成对出现或者禁止
在C++11中增加了move操作,如果需要某个类支持移动操作,那么需要实现移动构造和移动赋值操作符。
移动构造函数和移动赋值操作符都是具有移动语义的,应该同时出现或者禁?止。
移动构造函数和移动赋值操作符都是具有移动语义的,应该同时出现或者禁止。
```cpp
// 同时出现
class Foo {
......@@ -1524,7 +1484,7 @@ public:
```cpp
class Sub : public Base {
public:
Sub() : numbers_(NULL)
Sub() : numbers_(nullptr)
{
}
......@@ -1538,7 +1498,7 @@ public:
{
const size_t numberCount = 100;
numbers_ = new (std::nothrow) int[numberCount];
if (numbers_ == NULL) {
if (numbers_ == nullptr) {
return -1;
}
......@@ -1738,8 +1698,8 @@ void FooListAddNode(void *node) // Bad: 这里用 void * 类型传递参数
void MakeTheList()
{
FooNode *foo = NULL;
BarNode *bar = NULL;
FooNode *foo = nullptr;
BarNode *bar = nullptr;
...
FooListAddNode(bar); // Wrong: 这里本意是想传递参数 foo,但错传了 bar,却没有报错
......@@ -2097,7 +2057,7 @@ const int MAX_ARRAY_SIZE = 100;
int* numberArray = new int[MAX_ARRAY_SIZE];
...
delete numberArray;
numberArray = NULL;
numberArray = nullptr;
```
正确写法:
......@@ -2106,7 +2066,7 @@ const int MAX_ARRAY_SIZE = 100;
int* numberArray = new int[MAX_ARRAY_SIZE];
...
delete[] numberArray;
numberArray = NULL;
numberArray = nullptr;
```
### <a name="a9-4-1"></a>建议9.4.1 使用 RAII 特性来帮助追踪动态分配
......@@ -2206,7 +2166,7 @@ void Fun2()
auto_ptr<T> p1(new T);
auto_ptr<T> p2 = p1;
```
当执行完第2行语句后,p1已经不再指向第1行中分配的对象,而是变为NULL。正因为如此,auto_ptr不能被置于各种标准容器中。
当执行完第2行语句后,p1已经不再指向第1行中分配的对象,而是变为nullptr。正因为如此,auto_ptr不能被置于各种标准容器中。
转移所有权的行为通常不是期望的结果。对于必须转移所有权的场景,也不应该使用隐式转移的方式。这往往需要程序员对使用auto_ptr的代码保持额外的谨慎,否则出现对空指针的访问。
使用auto_ptr常见的有两种场景,一是作为智能指针传递到产生auto_ptr的函数外部,二是使用auto_ptr作为RAII管理类,在超出auto_ptr的生命周期时自动释放资源。
对于第1种场景,可以使用std::shared_ptr来代替。
......
......@@ -6,75 +6,64 @@
如果您以前从未订阅过邮件列表,请参照下面的操作步骤。
1. 先发一个空邮件到您需要订阅的邮件列表。
2. 稍后您会收到一封确认邮件,对它进行回复即可完成订阅。
3. 在订阅成功后,请再发送您的问题到该邮件地址,那么所有订阅该邮件组的其它用户将会收到您的邮件,并做出分享。
1. 点击您想要订阅的邮件列表的名称。
2. 浏览器将跳转到该邮件列表的订阅页面,那里将提供有关如何订阅的说明。
3. 阅读订阅说明,您需要提供一个您希望用来订阅邮件列表的电子邮件地址。
4. 输入您的电子邮件地址并点击订阅,您将收到一封电子邮件,要求您确认订阅。
5. 回复您收到的电子邮件以确认您的订阅。
6. 最后您将收到来自一封来自邮件列表的欢迎邮件。
**表 1** : 邮件列表
<a name="table198701222219"></a>
<table><thead align="left"><tr id="row16871202215210"><th class="cellrowborder" valign="top" width="14.591459145914593%" id="mcps1.2.5.1.1"><p id="p1871122216211"><a name="p1871122216211"></a><a name="p1871122216211"></a>列表名称</p>
<table><thead align="left"><tr id="row16871202215210"><th class="cellrowborder" valign="top" width="20.757924207579244%" id="mcps1.2.4.1.1"><p id="p128719221213"><a name="p128719221213"></a><a name="p128719221213"></a>邮件地址</p>
</th>
<th class="cellrowborder" valign="top" width="20.162016201620162%" id="mcps1.2.5.1.2"><p id="p128719221213"><a name="p128719221213"></a><a name="p128719221213"></a>邮件地址</p>
<th class="cellrowborder" valign="top" width="11.65883411658834%" id="mcps1.2.4.1.2"><p id="p9227211844"><a name="p9227211844"></a><a name="p9227211844"></a>简介</p>
</th>
<th class="cellrowborder" valign="top" width="7.520752075207521%" id="mcps1.2.5.1.3"><p id="p9227211844"><a name="p9227211844"></a><a name="p9227211844"></a>类型</p>
</th>
<th class="cellrowborder" valign="top" width="57.72577257725773%" id="mcps1.2.5.1.4"><p id="p28717224216"><a name="p28717224216"></a><a name="p28717224216"></a>功能描述</p>
<th class="cellrowborder" valign="top" width="67.58324167583241%" id="mcps1.2.4.1.3"><p id="p28717224216"><a name="p28717224216"></a><a name="p28717224216"></a>功能描述</p>
</th>
</tr>
</thead>
<tbody><tr id="row1487115222219"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p108711522627"><a name="p108711522627"></a><a name="p108711522627"></a>Community</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p142153615915"><a name="p142153615915"></a><a name="p142153615915"></a>contact.openharmony@openatom.org</p>
<tbody><tr id="row1487115222219"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p142153615915"><a name="p142153615915"></a><a name="p142153615915"></a>contact@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p72211218412"><a name="p72211218412"></a><a name="p72211218412"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p72211218412"><a name="p72211218412"></a><a name="p72211218412"></a>公用邮箱</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p1087114221623"><a name="p1087114221623"></a><a name="p1087114221623"></a><span id="text11580114031511"><a name="text11580114031511"></a><a name="text11580114031511"></a>OpenHarmony</span>社区公共邮箱。<span>开发者CLA协议签署可以发邮件到此邮箱。</span></p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p1087114221623"><a name="p1087114221623"></a><a name="p1087114221623"></a><span id="text11580114031511"><a name="text11580114031511"></a><a name="text11580114031511"></a>OpenHarmony</span>社区公共邮箱。<span>开发者CLA协议签署可以发邮件到此邮箱。</span></p>
</td>
</tr>
<tr id="row107737404215"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p1887112213210"><a name="p1887112213210"></a><a name="p1887112213210"></a>Dev</p>
<tr id="row107737404215"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p148951611957"><a name="p148951611957"></a><a name="p148951611957"></a>dev@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p148951611957"><a name="p148951611957"></a><a name="p148951611957"></a>dev.openharmony@openatom.org</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p822122113410"><a name="p822122113410"></a><a name="p822122113410"></a>开发邮件列表</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p822122113410"><a name="p822122113410"></a><a name="p822122113410"></a>Public</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p16774144174210"><a name="p16774144174210"></a><a name="p16774144174210"></a><span id="text20103211124216"><a name="text20103211124216"></a><a name="text20103211124216"></a>OpenHarmony</span><span>社区开发讨论邮件列表,任何社区开发相关话题都可以在邮件列表讨论。任何开发者可订阅。</span></p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p16774144174210"><a name="p16774144174210"></a><a name="p16774144174210"></a><span id="text20103211124216"><a name="text20103211124216"></a><a name="text20103211124216"></a>OpenHarmony</span><span>社区开发讨论邮件列表,任何社区开发相关话题都可以在邮件列表讨论。任何开发者可</span><a href="https://lists.openatom.io/postorius/lists/dev.openharmony.io" target="_blank" rel="noopener noreferrer">订阅</a><span></span></p>
</td>
</tr>
<tr id="row7871622728"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p10856181211422"><a name="p10856181211422"></a><a name="p10856181211422"></a>CICD</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p44601613113817"><a name="p44601613113817"></a><a name="p44601613113817"></a>cicd.openharmony@openatom.org</p>
<tr id="row7871622728"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p44601613113817"><a name="p44601613113817"></a><a name="p44601613113817"></a>cicd@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p222202115413"><a name="p222202115413"></a><a name="p222202115413"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p222202115413"><a name="p222202115413"></a><a name="p222202115413"></a>CI邮件列表</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p16871822628"><a name="p16871822628"></a><a name="p16871822628"></a><span id="text174641244154914"><a name="text174641244154914"></a><a name="text174641244154914"></a>OpenHarmony</span>社区CI门禁项目邮件列表</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p16871822628"><a name="p16871822628"></a><a name="p16871822628"></a><span id="text174641244154914"><a name="text174641244154914"></a><a name="text174641244154914"></a>OpenHarmony</span>社区CICD构建邮件列表,任何开发者可<a href="https://lists.openatom.io/postorius/lists/cicd.openharmony.io" target="_blank" rel="noopener noreferrer">订阅</a></p>
</td>
</tr>
<tr id="row8715135275716"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p1371675285717"><a name="p1371675285717"></a><a name="p1371675285717"></a><span>PMC</span></p>
<tr id="row8715135275716"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p3716452175711"><a name="p3716452175711"></a><a name="p3716452175711"></a>pmc@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p3716452175711"><a name="p3716452175711"></a><a name="p3716452175711"></a>pmc.openharmony@openatom.org</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p112292113412"><a name="p112292113412"></a><a name="p112292113412"></a>PMC邮件列表</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p112292113412"><a name="p112292113412"></a><a name="p112292113412"></a>Private</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p1571612525573"><a name="p1571612525573"></a><a name="p1571612525573"></a><span>PMC</span><span>讨论邮件列表,PMC成员可订阅。</span></p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p1571612525573"><a name="p1571612525573"></a><a name="p1571612525573"></a>PMC讨论邮件列表,PMC成员可<a href="https://lists.openatom.io/postorius/lists/pmc.openharmony.io/" target="_blank" rel="noopener noreferrer">订阅</a></p>
</td>
</tr>
<tr id="row77591655145717"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p112614230585"><a name="p112614230585"></a><a name="p112614230585"></a>安全漏洞</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p311833519387"><a name="p311833519387"></a><a name="p311833519387"></a>scy.openharmony@openatom.org</p>
<tr id="row77591655145717"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p311833519387"><a name="p311833519387"></a><a name="p311833519387"></a>scy@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p823122110410"><a name="p823122110410"></a><a name="p823122110410"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p11530134203816"><a name="p11530134203816"></a><a name="p11530134203816"></a>安全问题邮箱</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p20127152355810"><a name="p20127152355810"></a><a name="p20127152355810"></a>Public开发者反馈OpenHarmony安全问题邮箱。</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p20127152355810"><a name="p20127152355810"></a><a name="p20127152355810"></a>开发者可反馈<span id="text162005351389"><a name="text162005351389"></a><a name="text162005351389"></a>OpenHarmony</span>安全问题到此邮箱。</p>
</td>
</tr>
<tr id="row1713010314581"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="p611923375817"><a name="p611923375817"></a><a name="p611923375817"></a><span>安全讨论</span></p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="p311943316586"><a name="p311943316586"></a><a name="p311943316586"></a>scy-priv.openharmony@openatom.org</p>
<tr id="row1713010314581"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="p311943316586"><a name="p311943316586"></a><a name="p311943316586"></a>scy-priv@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="p10231211144"><a name="p10231211144"></a><a name="p10231211144"></a>Private</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="p10231211144"><a name="p10231211144"></a><a name="p10231211144"></a>安全组邮件列表</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="p17119183319584"><a name="p17119183319584"></a><a name="p17119183319584"></a>Private<span>安全组成员安全问题处理讨论邮件列表,安全组成员可订阅。</span></p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="p17119183319584"><a name="p17119183319584"></a><a name="p17119183319584"></a>安全组成员安全问题处理讨论邮件列表,安全组成员可<a href="https://lists.openatom.io/postorius/lists/scy-priv.openharmony.io/" target="_blank" rel="noopener noreferrer">订阅</a></p>
</td>
</tr>
</tbody>
......
......@@ -2,7 +2,7 @@
通过签署贡献协议(“本协议”),签署的“贡献者”同意接受“本协议”并受“本协议”约束。“本协议”适用于“贡献者”提交给OpenHarmony区 (“社区”)的全部项目(后称“项目”)的“贡献”,无论“贡献”是在签署日期之前,签署时还是之后提供。
**“贡献”** 是指受版权法保护的,由“贡献者”有意“提交”以包含在“项目”所分发软件中任何作品。“提交”是指以电子,口头或书面交流的任何形式送给“社区”管理方或其代表,包括但不限于“社区”管理方为管理的为讨论和改进项目所提供的电子邮件列表上的交流,源代码控制系统以及由“社区”管理方或其代表管理的问题跟踪系统,但不包括由“我”明确标记或以书面形式指定为“非贡献”的交流。
**“贡献”** 是指受版权法保护的,由“贡献者”有意“提交”以包含在“项目”所分发软件中任何作品。“提交”是指以电子,口头或书面交流的任何形式送给“社区”管理方(即开放原子开源基金会)或其代表,包括但不限于“社区”管理方为管理的为讨论和改进项目所提供的电子邮件列表上的交流,源代码控制系统以及由“社区”管理方或其代表管理的问题跟踪系统,但不包括由“我”明确标记或以书面形式指定为“非贡献”的交流。
**“贡献者”或“我”**是指下面签名栏中标明的个人或法人实体。对于法人实体,做出“贡献”的实体以及由该实体控制、受其控制或受其共同控制的所有其他实体均被视为“贡献者”。就本定义而言,“控制”是指有受控方或共同受控方至少50%直接或间接的投票权,资金或其他有价证券。
......
......@@ -2,7 +2,7 @@
通过签署贡献协议(“本协议”),签署的“贡献者”同意接受“本协议”并受“本协议”约束。“本协议”适用于“贡献者”提交给OpenHarmony区 (“社区”)的全部项目(后称“项目”)的“贡献”,无论“贡献”是在签署日期之前,签署时还是之后提供。
**“贡献”** 是指受版权法保护的,由“贡献者”有意“提交”以包含在“项目”所分发软件中任何作品。“提交”是指以电子,口头或书面交流的任何形式送给“社区”管理方或其代表,包括但不限于“社区”管理方为管理的为讨论和改进项目所提供的电子邮件列表上的交流,源代码控制系统以及由“社区”管理方或其代表管理的问题跟踪系统,但不包括由“我”明确标记或以书面形式指定为“非贡献”的交流。
**“贡献”** 是指受版权法保护的,由“贡献者”有意“提交”以包含在“项目”所分发软件中任何作品。“提交”是指以电子,口头或书面交流的任何形式送给“社区”管理方(即开放原子开源基金会)或其代表,包括但不限于“社区”管理方为管理的为讨论和改进项目所提供的电子邮件列表上的交流,源代码控制系统以及由“社区”管理方或其代表管理的问题跟踪系统,但不包括由“我”明确标记或以书面形式指定为“非贡献”的交流。
**“贡献者”或“我”**是指下面签名栏中标明的个人或法人实体。对于法人实体,做出“贡献”的实体以及由该实体控制、受其控制或受其共同控制的所有其他实体均被视为“贡献者”。就本定义而言,“控制”是指有受控方或共同受控方至少50%直接或间接的投票权,资金或其他有价证券。
......
......@@ -17,8 +17,8 @@
## 社区安全问题披露<a name="section725624119448"></a>
- 安全处理流程---待补充
- 安全处理流程
- 安全披露信息---待补充
- 安全披露信息
......@@ -68,7 +68,7 @@
2. 下载\(注意没有repo branch参数\)
```
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo init -u https://gitee.com/openharmony/manifest.git -b master
repo sync -c
```
......
......@@ -6,12 +6,12 @@ This project provides documents including the quick start, development guide, an
- quick-start: [Getting Started](quick-start/Readme-EN.md)
- get-code: [Source Code Acquisition/Tool Acquisition](get-code/Readme-EN.md)
- driver: [Driver Usage Guidelines](driver/Readme-EN.md)
- driver: [Device Development Guidelines](driver/Readme-EN.md)
- kernel: [Kernel Usage Guidelines](kernel/Readme-EN.md)
- subsystems: [Subsystem Development Guidelines](subsystems/Readme-EN.md)
- bundles: [Bundle Development](bundles/Readme-EN.md)
- guide: [Device Development Guidelines](guide/Readme-EN.md)
- security: [Privacy and Securit](security/Readme-EN.md)
- security: [Privacy and Security](security/Readme-EN.md)
- api-LinkIoT: [LinkIoT Modules API](api/api-LinkIoT/Readme-EN.md)
- api-SmartVision-Devices: [SmartVision Devices API](api/api-SmartVision-Devices/Readme-EN.md)
- contribute: [Contribution](contribute/contribution.md)
......
......@@ -2,87 +2,76 @@
If you encounter any problems when using OpenHarmony, please join the email group for discussion.
## How Do I Subscribe to a Mailing List?<a name="en-us_topic_0000001051853133_section103251821112117"></a>
## How Do I Subscribe to a Mail List?<a name="en-us_topic_0000001051853133_section103251821112117"></a>
If you have never subscribed to a mailing list before, follow the steps below:
If you have never subscribed to a mail list before, follow the steps below:
1. Send an empty mail to the mailing list you want to subscribe to. You will receive a confirmation email.
2. Reply to the confirmation email. The subscription is successful.
3. Send your question to the email address. All other users who subscribe to the mailing list will receive your email and share it.
1. Click the name of the mail list that you want to subscribe to.
2. Wait until the browser goes to the subscription page of the mail list, which provides instructions on how to subscribe.
3. Read the subscription instructions and provide an email address that you want to use to subscribe to the mail list.
4. Enter your email address and click **Subscribe**. You will receive an email asking you to confirm the subscription.
5. Reply the email to confirm your subscription.
6. At last, you will receive a welcome email from the email list.
**Table 1** Email list
<a name="en-us_topic_0000001051853133_table198701222219"></a>
<table><thead align="left"><tr id="en-us_topic_0000001051853133_row16871202215210"><th class="cellrowborder" valign="top" width="14.591459145914593%" id="mcps1.2.5.1.1"><p id="en-us_topic_0000001051853133_p1871122216211"><a name="en-us_topic_0000001051853133_p1871122216211"></a><a name="en-us_topic_0000001051853133_p1871122216211"></a>List Name</p>
<table><thead align="left"><tr id="en-us_topic_0000001051853133_row16871202215210"><th class="cellrowborder" valign="top" width="20.757924207579244%" id="mcps1.2.4.1.1"><p id="en-us_topic_0000001051853133_p128719221213"><a name="en-us_topic_0000001051853133_p128719221213"></a><a name="en-us_topic_0000001051853133_p128719221213"></a>Email Address</p>
</th>
<th class="cellrowborder" valign="top" width="20.162016201620162%" id="mcps1.2.5.1.2"><p id="en-us_topic_0000001051853133_p128719221213"><a name="en-us_topic_0000001051853133_p128719221213"></a><a name="en-us_topic_0000001051853133_p128719221213"></a>Email Address</p>
<th class="cellrowborder" valign="top" width="11.65883411658834%" id="mcps1.2.4.1.2"><p id="en-us_topic_0000001051853133_p9227211844"><a name="en-us_topic_0000001051853133_p9227211844"></a><a name="en-us_topic_0000001051853133_p9227211844"></a>Introduction</p>
</th>
<th class="cellrowborder" valign="top" width="7.520752075207521%" id="mcps1.2.5.1.3"><p id="en-us_topic_0000001051853133_p9227211844"><a name="en-us_topic_0000001051853133_p9227211844"></a><a name="en-us_topic_0000001051853133_p9227211844"></a>Type</p>
</th>
<th class="cellrowborder" valign="top" width="57.72577257725773%" id="mcps1.2.5.1.4"><p id="en-us_topic_0000001051853133_p28717224216"><a name="en-us_topic_0000001051853133_p28717224216"></a><a name="en-us_topic_0000001051853133_p28717224216"></a>Description</p>
<th class="cellrowborder" valign="top" width="67.58324167583241%" id="mcps1.2.4.1.3"><p id="en-us_topic_0000001051853133_p28717224216"><a name="en-us_topic_0000001051853133_p28717224216"></a><a name="en-us_topic_0000001051853133_p28717224216"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="en-us_topic_0000001051853133_row1487115222219"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p108711522627"><a name="en-us_topic_0000001051853133_p108711522627"></a><a name="en-us_topic_0000001051853133_p108711522627"></a>Community</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p142153615915"><a name="en-us_topic_0000001051853133_p142153615915"></a><a name="en-us_topic_0000001051853133_p142153615915"></a>contact@openharmony.io</p>
<tbody><tr id="en-us_topic_0000001051853133_row1487115222219"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p142153615915"><a name="en-us_topic_0000001051853133_p142153615915"></a><a name="en-us_topic_0000001051853133_p142153615915"></a>contact@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p72211218412"><a name="en-us_topic_0000001051853133_p72211218412"></a><a name="en-us_topic_0000001051853133_p72211218412"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p72211218412"><a name="en-us_topic_0000001051853133_p72211218412"></a><a name="en-us_topic_0000001051853133_p72211218412"></a>Public mailbox</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p1087114221623"><a name="en-us_topic_0000001051853133_p1087114221623"></a><a name="en-us_topic_0000001051853133_p1087114221623"></a>Public email address of the <span id="en-us_topic_0000001051853133_text11580114031511"><a name="en-us_topic_0000001051853133_text11580114031511"></a><a name="en-us_topic_0000001051853133_text11580114031511"></a>OpenHarmony</span> community. You can send emails to this email address to sign the Contributor License Agreement (CLA).</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p1087114221623"><a name="en-us_topic_0000001051853133_p1087114221623"></a><a name="en-us_topic_0000001051853133_p1087114221623"></a>Public mailbox of the <span id="en-us_topic_0000001051853133_text11580114031511"><a name="en-us_topic_0000001051853133_text11580114031511"></a><a name="en-us_topic_0000001051853133_text11580114031511"></a>OpenHarmony</span> community. You can send emails to this mailbox to sign the Contributor License Agreement (CLA).</p>
</td>
</tr>
<tr id="en-us_topic_0000001051853133_row107737404215"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p1887112213210"><a name="en-us_topic_0000001051853133_p1887112213210"></a><a name="en-us_topic_0000001051853133_p1887112213210"></a>Dev</p>
<tr id="en-us_topic_0000001051853133_row107737404215"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p148951611957"><a name="en-us_topic_0000001051853133_p148951611957"></a><a name="en-us_topic_0000001051853133_p148951611957"></a>dev@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p148951611957"><a name="en-us_topic_0000001051853133_p148951611957"></a><a name="en-us_topic_0000001051853133_p148951611957"></a>dev@openharmony.io</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p822122113410"><a name="en-us_topic_0000001051853133_p822122113410"></a><a name="en-us_topic_0000001051853133_p822122113410"></a>Development mail list</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p822122113410"><a name="en-us_topic_0000001051853133_p822122113410"></a><a name="en-us_topic_0000001051853133_p822122113410"></a>Public</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p16774144174210"><a name="en-us_topic_0000001051853133_p16774144174210"></a><a name="en-us_topic_0000001051853133_p16774144174210"></a><span id="en-us_topic_0000001051853133_text20103211124216"><a name="en-us_topic_0000001051853133_text20103211124216"></a><a name="en-us_topic_0000001051853133_text20103211124216"></a>OpenHarmony</span> community development discussion group. Any topics related to community development can be discussed here. Any one can subscribe to it.</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p16774144174210"><a name="en-us_topic_0000001051853133_p16774144174210"></a><a name="en-us_topic_0000001051853133_p16774144174210"></a><span id="en-us_topic_0000001051853133_text20103211124216"><a name="en-us_topic_0000001051853133_text20103211124216"></a><a name="en-us_topic_0000001051853133_text20103211124216"></a>OpenHarmony</span> community development discussion group. Any topics related to community development can be discussed here. Any one can <a href="https://lists.openatom.io/postorius/lists/dev.openharmony.io" target="_blank" rel="noopener noreferrer">subscribe</a> to it.</p>
</td>
</tr>
<tr id="en-us_topic_0000001051853133_row7871622728"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p10856181211422"><a name="en-us_topic_0000001051853133_p10856181211422"></a><a name="en-us_topic_0000001051853133_p10856181211422"></a>CICD</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p44601613113817"><a name="en-us_topic_0000001051853133_p44601613113817"></a><a name="en-us_topic_0000001051853133_p44601613113817"></a>cicd@openharmony.io</p>
<tr id="en-us_topic_0000001051853133_row7871622728"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p44601613113817"><a name="en-us_topic_0000001051853133_p44601613113817"></a><a name="en-us_topic_0000001051853133_p44601613113817"></a>cicd@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p222202115413"><a name="en-us_topic_0000001051853133_p222202115413"></a><a name="en-us_topic_0000001051853133_p222202115413"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p222202115413"><a name="en-us_topic_0000001051853133_p222202115413"></a><a name="en-us_topic_0000001051853133_p222202115413"></a>CI mail list</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p16871822628"><a name="en-us_topic_0000001051853133_p16871822628"></a><a name="en-us_topic_0000001051853133_p16871822628"></a>This mailing list is used for discussing the <span id="en-us_topic_0000001051853133_text174641244154914"><a name="en-us_topic_0000001051853133_text174641244154914"></a><a name="en-us_topic_0000001051853133_text174641244154914"></a>OpenHarmony</span> community CI access control.</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p16871822628"><a name="en-us_topic_0000001051853133_p16871822628"></a><a name="en-us_topic_0000001051853133_p16871822628"></a>The <span id="en-us_topic_0000001051853133_text174641244154914"><a name="en-us_topic_0000001051853133_text174641244154914"></a><a name="en-us_topic_0000001051853133_text174641244154914"></a>OpenHarmony</span> community CI/CD builds a mail list that any developer can <a href="https://lists.openatom.io/postorius/lists/cicd.openharmony.io" target="_blank" rel="noopener noreferrer">subscribe</a> to.</p>
</td>
</tr>
<tr id="en-us_topic_0000001051853133_row8715135275716"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p1371675285717"><a name="en-us_topic_0000001051853133_p1371675285717"></a><a name="en-us_topic_0000001051853133_p1371675285717"></a>PMC</p>
<tr id="en-us_topic_0000001051853133_row8715135275716"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p3716452175711"><a name="en-us_topic_0000001051853133_p3716452175711"></a><a name="en-us_topic_0000001051853133_p3716452175711"></a>pmc@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p3716452175711"><a name="en-us_topic_0000001051853133_p3716452175711"></a><a name="en-us_topic_0000001051853133_p3716452175711"></a>pmc@openharmony.io</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p112292113412"><a name="en-us_topic_0000001051853133_p112292113412"></a><a name="en-us_topic_0000001051853133_p112292113412"></a>PMC mail list</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p112292113412"><a name="en-us_topic_0000001051853133_p112292113412"></a><a name="en-us_topic_0000001051853133_p112292113412"></a>Private</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p1571612525573"><a name="en-us_topic_0000001051853133_p1571612525573"></a><a name="en-us_topic_0000001051853133_p1571612525573"></a>Mailing list for PMC discussion. It can be subscribed to by PMC members.</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p1571612525573"><a name="en-us_topic_0000001051853133_p1571612525573"></a><a name="en-us_topic_0000001051853133_p1571612525573"></a>Mail list for PMC discussion. It can be <a href="https://lists.openatom.io/postorius/lists/pmc.openharmony.io/" target="_blank" rel="noopener noreferrer">subscribed</a> to by PMC members.</p>
</td>
</tr>
<tr id="en-us_topic_0000001051853133_row77591655145717"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p112614230585"><a name="en-us_topic_0000001051853133_p112614230585"></a><a name="en-us_topic_0000001051853133_p112614230585"></a>Security vulnerabilities</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p311833519387"><a name="en-us_topic_0000001051853133_p311833519387"></a><a name="en-us_topic_0000001051853133_p311833519387"></a>scy@openharmony.io</p>
<tr id="en-us_topic_0000001051853133_row77591655145717"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p311833519387"><a name="en-us_topic_0000001051853133_p311833519387"></a><a name="en-us_topic_0000001051853133_p311833519387"></a>scy@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p823122110410"><a name="en-us_topic_0000001051853133_p823122110410"></a><a name="en-us_topic_0000001051853133_p823122110410"></a>Public</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p11530134203816"><a name="en-us_topic_0000001051853133_p11530134203816"></a><a name="en-us_topic_0000001051853133_p11530134203816"></a>Mail list for security issues</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p20127152355810"><a name="en-us_topic_0000001051853133_p20127152355810"></a><a name="en-us_topic_0000001051853133_p20127152355810"></a>Email address for you to report <span id="en-us_topic_0000001051853133_text893492535111"><a name="en-us_topic_0000001051853133_text893492535111"></a><a name="en-us_topic_0000001051853133_text893492535111"></a>OpenHarmony</span> security issues.</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p20127152355810"><a name="en-us_topic_0000001051853133_p20127152355810"></a><a name="en-us_topic_0000001051853133_p20127152355810"></a>Email address for you to report <span id="en-us_topic_0000001051853133_text162005351389"><a name="en-us_topic_0000001051853133_text162005351389"></a><a name="en-us_topic_0000001051853133_text162005351389"></a>OpenHarmony</span> security issues.</p>
</td>
</tr>
<tr id="en-us_topic_0000001051853133_row1713010314581"><td class="cellrowborder" valign="top" width="14.591459145914593%" headers="mcps1.2.5.1.1 "><p id="en-us_topic_0000001051853133_p611923375817"><a name="en-us_topic_0000001051853133_p611923375817"></a><a name="en-us_topic_0000001051853133_p611923375817"></a>Security discussion</p>
</td>
<td class="cellrowborder" valign="top" width="20.162016201620162%" headers="mcps1.2.5.1.2 "><p id="en-us_topic_0000001051853133_p311943316586"><a name="en-us_topic_0000001051853133_p311943316586"></a><a name="en-us_topic_0000001051853133_p311943316586"></a>scy-priv@openharmony.io</p>
<tr id="en-us_topic_0000001051853133_row1713010314581"><td class="cellrowborder" valign="top" width="20.757924207579244%" headers="mcps1.2.4.1.1 "><p id="en-us_topic_0000001051853133_p311943316586"><a name="en-us_topic_0000001051853133_p311943316586"></a><a name="en-us_topic_0000001051853133_p311943316586"></a>scy-priv@openharmony.io</p>
</td>
<td class="cellrowborder" valign="top" width="7.520752075207521%" headers="mcps1.2.5.1.3 "><p id="en-us_topic_0000001051853133_p10231211144"><a name="en-us_topic_0000001051853133_p10231211144"></a><a name="en-us_topic_0000001051853133_p10231211144"></a>Private</p>
<td class="cellrowborder" valign="top" width="11.65883411658834%" headers="mcps1.2.4.1.2 "><p id="en-us_topic_0000001051853133_p10231211144"><a name="en-us_topic_0000001051853133_p10231211144"></a><a name="en-us_topic_0000001051853133_p10231211144"></a>Security group mail list</p>
</td>
<td class="cellrowborder" valign="top" width="57.72577257725773%" headers="mcps1.2.5.1.4 "><p id="en-us_topic_0000001051853133_p17119183319584"><a name="en-us_topic_0000001051853133_p17119183319584"></a><a name="en-us_topic_0000001051853133_p17119183319584"></a>The security group members can subscribe to this email list to discuss security issues.</p>
<td class="cellrowborder" valign="top" width="67.58324167583241%" headers="mcps1.2.4.1.3 "><p id="en-us_topic_0000001051853133_p17119183319584"><a name="en-us_topic_0000001051853133_p17119183319584"></a><a name="en-us_topic_0000001051853133_p17119183319584"></a>The security group members can <a href="https://lists.openatom.io/postorius/lists/scy-priv.openharmony.io/" target="_blank" rel="noopener noreferrer">subscribe</a> to this email list to discuss security issues.</p>
</td>
</tr>
</tbody>
</table>
## How Do I Send Emails to a Mailing List?<a name="en-us_topic_0000001051853133_section09801118222"></a>
## How Do I Send Emails to a Mail List?<a name="en-us_topic_0000001051853133_section09801118222"></a>
To send an email to a specified mailing list, send your email to the address listed in the table above.
To send an email to a specified mail list, send your email to the address listed in the table above.
In this way, all community members in this mailing list will receive your email.
In this way, all community members in this mail list will receive your email.
......@@ -17,8 +17,8 @@ For details, see [Contribution Process](contribution-process.md).
## Security Issue Disclosure<a name="en-us_topic_0000001051566732_section725624119448"></a>
- Security handling procedure \(To be supplemented\)
- Security handling procedure
- Security disclosure information \(To be supplemented\)
- Security disclosure information
......@@ -68,7 +68,7 @@ Perform the following steps to download the code in the repository to your compu
2. Download code repositories. \(There is no **repo branch** parameter.\)
```
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo init -u https://gitee.com/openharmony/manifest.git -b master
repo sync -c
```
......
......@@ -2,17 +2,17 @@
By signing this Agreement For Contribution \(this Agreement\), the undersigned Contributor agrees to accept and be legally bound by this Agreement. This Agreement applies to the Contribution submitted by Contributor to all the projects of OpenHarmony Community \(“Project”\), whether provided before, on or after the signing date.
**Contribution** shall mean any work protectable under copyright lawthat is intentionally submitted by Contributor for inclusion in the software distributed by the Project. "submitted" means any form of electronic, verbal, or written communication sent to the hoster of the openEuler Community \(Hoster\) 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 Hoster for the purpose of discussing and improving the Project, but excluding communication that is conspicuously marked or otherwise designated in writing by Me as "Not a Contribution."
**Contribution** shall mean any work protectable under copyright lawthat is intentionally submitted by Contributor for inclusion in the software distributed by the Project. "submitted" means any form of electronic, verbal, or written communication sent to the hoster of the OpenHarmony Community \(Hoster, i.e. OPENATOM FOUNDATION\) 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 Hoster for the purpose of discussing and improving the Project, but excluding communication that is conspicuously marked or otherwise designated in writing by Me as "Not a Contribution."
**Contributor or I or Me or My** shall mean the individual or legal entity identified in the signature block below. For legal entity, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, ‘control’ means direct or indirect ownership of at least fifty percent \(50%\) of the voting power, capital or other securities of controlled or commonly controlled entity.
**Contributor or I or Me or My** shall mean the individual or legal entity identified in the signature block below. For legal entity, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, 'control' means direct or indirect ownership of at least fifty percent \(50%\) of the voting power, capital or other securities of controlled or commonly controlled entity.
Each Contributor hereby grants to the Hoster and the recipients of software distributed by the Project a perpetual, worldwide, royalty-free, non-exclusive, irrevocable, sub-licensable copyright license to reproduce, use, modify, or distribute its Contribution, with modification or not.
Each Contributor hereby grants to the Hoster and recipients of the software distributed by the Project a perpetual, worldwide, royalty-free, non-exclusive, irrevocable patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Project software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others modification or other combinations. In case the license adopted by the specific software distributed by the Project has further restriction on the patent license granted to the software recipients, for example, restricts the recipients to file patent litigation or enforcement against Contribution or such software, then the patent license to the recipients of the specific Project license prevails.
Each Contributor hereby grants to the Hoster and recipients of the software distributed by the Project a perpetual, worldwide, royalty-free, non-exclusive, irrevocable patent license to make, have made, use, offer for sale, sell, import or otherwise transfer its Contribution where such patent license is only limited to the patent claims owned or controlled by such Contributor now or in future which will be necessarily infringed by its Contribution alone, or by combination of the Contribution with the Project software to which the Contribution was contributed, excluding of any patent claims solely be infringed by your or others modification or other combinations. In case the license adopted by the specific software distributed by the Project has further restriction on the patent license granted to the software recipients, for example, restricts the recipients to file patent litigation or enforcement against Contribution or such software, then the patent license to the recipients of the specific Project license prevails.
Contributor represents that I’m the copyright owner of the Contribution or I’m authorized by the copyright owner to make such Contribution, and I’m legally entitled to grant the rights set out in this Agreement and the License;
Contributor represents that I’ m not aware any of My Contribution has infringed or will infringe any third party's copyrights, trademarks, patents, or other intellectual property rights.
Contributor represents that I’m not aware any of My Contribution has infringed or will infringe any third party's copyrights, trademarks, patents, or other intellectual property rights.
Except as otherwise stated in the Agreement, Contribution is provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.
......
......@@ -2,7 +2,7 @@
By signing this Agreement For Contribution \(this Agreement\), the undersigned Contributor agrees to accept and be legally bound by this Agreement. This Agreement applies to the Contribution submitted by Contributor to all the projects of OpenHarmony Community \(“Project”\), whether provided before, on or after the signing date.
**Contribution** shall mean any work protectable under copyright lawthat is intentionally submitted by Contributor for inclusion in the software distributed by the Project. "submitted" means any form of electronic, verbal, or written communication sent to the hoster of the openEuler Community \(Hoster\) 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 Hoster for the purpose of discussing and improving the Project, but excluding communication that is conspicuously marked or otherwise designated in writing by Me as "Not a Contribution."
**Contribution** shall mean any work protectable under copyright lawthat is intentionally submitted by Contributor for inclusion in the software distributed by the Project. "submitted" means any form of electronic, verbal, or written communication sent to the hoster of the OpenHarmony Community \(Hoster, i.e. OPENATOM FOUNDATION\) 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 Hoster for the purpose of discussing and improving the Project, but excluding communication that is conspicuously marked or otherwise designated in writing by Me as "Not a Contribution."
**Contributor or I or Me or My** shall mean the individual or legal entity identified in the signature block below. For legal entity, the entity making a Contribution and all other entities that control, are controlled by, or are under common control with that entity are considered to be a single Contributor. For the purposes of this definition, ‘control’ means direct or indirect ownership of at least fifty percent \(50%\) of the voting power, capital or other securities of controlled or commonly controlled entity.
......@@ -12,7 +12,7 @@ Each Contributor hereby grants to the Hoster and recipients of the software dist
Contributor represents that I’m the copyright owner of the Contribution or I’m authorized by the copyright owner to make such Contribution, and I’m legally entitled to grant the rights set out in this Agreement and the License;
Contributor represents that I’ m not aware any of My Contribution has infringed or will infringe any third party's copyrights, trademarks, patents, or other intellectual property rights.
Contributor represents that I’m not aware any of My Contribution has infringed or will infringe any third party's copyrights, trademarks, patents, or other intellectual property rights.
Except as otherwise stated in the Agreement, Contribution is provided without warranties of any kind, either express or implied. In no event shall any Contributor or copyright holder be liable to you for any damages, including, but not limited to any direct, or indirect, special or consequential damages arising from your use or inability to use the software or the Contribution in it, no matter how it’s caused or based on which legal theory, even if advised of the possibility of such damages.
......
......@@ -271,7 +271,7 @@ The following configuration tree is generated:
root {
module = "sample";
foo {
attribute0 = 0x0;
attr_0 = 0x0;
}
bar {
attr_1 = 0x1;
......@@ -280,7 +280,7 @@ root {
}
```
In the preceding example, the **bar** node configuration includes both the **attribute0** and **attribute1** values. The modification to **attribute0** in the **bar** node does not affect the **foo** node.
In the preceding example, the **bar** node configuration includes both the **attr\_0** and **attr\_1** values. The modification to **attr\_0** in the **bar** node does not affect the **foo** node.
The path of the **foo** node is not required if the **foo** node and the **bar** node are of the same level. Otherwise, the absolute path must be used. For details, see [Modifying a Reference](#section179799204716).
......
......@@ -100,28 +100,32 @@ Driver development based on the HDF consists of two parts: driver implementation
match_attr = "hdf_manager";
template host { // Host template. If the node (for example, sample_host) that inherits the template uses default values in the template, the values of the node fields can be omitted.
hostName = "";
priority = 100;
template deviceNode {
policy = 0;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "";
serviceName = "";
deviceMatchAttr = "";
priority = 100;
template device {
template deviceNode {
policy = 0;
priority = 100;
preload = 0;
permission = 0664;
moduleName = "";
serviceName = "";
deviceMatchAttr = "";
}
}
}
sample_host :: host{
hostName = "host0"; // Host name. The host node is used to store a certain type of drivers.
priority = 100; // Host startup priority (0-200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the host loading sequence is random.
device_sample :: deviceNode { // Node of the sample driver.
device_sample :: device { // Device node of sample
device0 :: deviceNode { // DeviceNode of the sample driver
policy = 1; // Driver service release policy. For details, see section Driver Service Management.
priority = 100; // Driver startup priority (0–200). A larger value indicates a lower priority. The default value 100 is recommended. If the priorities are the same, the device loading sequence is random.
preload = 0; // On-demand driver loading. For details, see "NOTE" at the end of this section.
permission = 0664; // Permission for the driver to create device nodes.
moduleName = "sample_driver"; // Driver name. The value of this field must be the same as the value of moduleName in the driver entry structure.
serviceName = "sample_service"; // Name of the service released by the driver. The name must be unique.
deviceMatchAttr = "sample_config"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver.
deviceMatchAttr = "sample_config"; // Keyword matching the private data of the driver. The value must be the same as that of match_attr in the private data configuration table of the driver.
}
}
}
}
......
......@@ -63,7 +63,7 @@ if (handle == NULL) {
After obtaining the device handle of an SDIO controller, exclusively claim the host before performing subsequent operations on the SDIO device.
void SdioClaimHost\(struct DevHandle\*handle\);
void SdioClaimHost\(struct DevHandle \*handle\);
**Table 2** Parameter description of SdioClaimHost
......
......@@ -41,7 +41,7 @@ You can download the source code or the corresponding solutions from the image l
<td class="cellrowborder" valign="top" width="34.1%" headers="mcps1.2.5.1.4 "><p id="p992993202517"><a name="p992993202517"></a><a name="p992993202517"></a><a href="http://tools.harmonyos.com/mirrors/os/1.0/code-1.0.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA-256 Verification Code</a></p>
</td>
</tr>
<tr id="row6929934252"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p0929163132512"><a name="p0929163132512"></a><a name="p0929163132512"></a>Hi3861 solutions</p>
<tr id="row6929934252"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p0929163132512"><a name="p0929163132512"></a><a name="p0929163132512"></a>Hi3861 solutions (binary)</p>
</td>
<td class="cellrowborder" valign="top" width="16.14%" headers="mcps1.2.5.1.2 "><p id="p392913162517"><a name="p392913162517"></a><a name="p392913162517"></a>1.0</p>
</td>
......@@ -50,7 +50,7 @@ You can download the source code or the corresponding solutions from the image l
<td class="cellrowborder" valign="top" width="34.1%" headers="mcps1.2.5.1.4 "><p id="p199296318252"><a name="p199296318252"></a><a name="p199296318252"></a><a href="http://tools.harmonyos.com/mirrors/os/1.0/wifiiot-1.0.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA-256 Verification Code</a></p>
</td>
</tr>
<tr id="row1293014352510"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p692917311258"><a name="p692917311258"></a><a name="p692917311258"></a>Hi3518 solutions</p>
<tr id="row1293014352510"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p692917311258"><a name="p692917311258"></a><a name="p692917311258"></a>Hi3518 solutions (binary)</p>
</td>
<td class="cellrowborder" valign="top" width="16.14%" headers="mcps1.2.5.1.2 "><p id="p49291935254"><a name="p49291935254"></a><a name="p49291935254"></a>1.0</p>
</td>
......@@ -59,7 +59,7 @@ You can download the source code or the corresponding solutions from the image l
<td class="cellrowborder" valign="top" width="34.1%" headers="mcps1.2.5.1.4 "><p id="p1392983162514"><a name="p1392983162514"></a><a name="p1392983162514"></a><a href="http://tools.harmonyos.com/mirrors/os/1.0/ipcamera_hi3518ev300-1.0.tar.gz.sha256" target="_blank" rel="noopener noreferrer">SHA-256 Verification Code</a></p>
</td>
</tr>
<tr id="row199306317255"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1693063122511"><a name="p1693063122511"></a><a name="p1693063122511"></a>Hi3516 solutions</p>
<tr id="row199306317255"><td class="cellrowborder" valign="top" width="25%" headers="mcps1.2.5.1.1 "><p id="p1693063122511"><a name="p1693063122511"></a><a name="p1693063122511"></a>Hi3516 solutions (binary)</p>
</td>
<td class="cellrowborder" valign="top" width="16.14%" headers="mcps1.2.5.1.2 "><p id="p169301335252"><a name="p169301335252"></a><a name="p169301335252"></a>1.0</p>
</td>
......@@ -234,7 +234,7 @@ Add the bundle \(**@ohos/demo** as an example\) to your project as follows:
Method 1 \(recommended\): Use the **repo** tool to download source code.
```
repo init -u https://gitee.com/openharmony/manifest.git -b master --no-repo-verify
repo init -u https://gitee.com/openharmony/manifest.git -b master
repo sync -c
```
......
# Adding Pages<a name="EN-US_TOPIC_0000001054607703"></a>
## Creating the Home Page \(Creating a Project\)<a name="section16935511143715"></a>
## Creating the Home Page<a name="section16935511143715"></a>
After the project is created, the **index** page is generated by default. The following figure shows the project directory.
......@@ -11,7 +11,7 @@ After the project is created, the **index** page is generated by default. The
Perform the following steps twice to create the rest two pages:
1. Right-click **pages** and choose **New** \> **JS Page**.
1. Right-click **pages** and choose **New** \> **JS Page** from the shortcut menu.
**Figure 2** Adding a page<a name="fig18740145216410"></a>
![](figures/adding-a-page.png "adding-a-page")
......
# Building the Home Page<a name="EN-US_TOPIC_0000001054927705"></a>
The application home page displays air quality information of the current city. There are two screens on the home page. Each screen displays the air quality information of a city, including the AQI and city name. The AQI value can be displayed in the form of a ring progress bar with animation.
The application home page displays air quality information of the current city. There are two screens on the home page. Each screen displays air quality information of a city, including the AQI and city name. The AQI value can be displayed in the form of a ring progress bar with animation.
1. The **<swiper\>** component is required to implement the switch between the two screens.
......@@ -20,7 +20,7 @@ The application home page displays air quality information of the current city.
}
```
This style class sets the height and width of the component. For device-side development, the component height and width must be explicitly specified. Otherwise, the component may fail to be displayed.
This style class sets the height and width of the component. During application development, the component height and width must be explicitly specified. Otherwise, the component may fail to be displayed.
- **index="\{\{swiperPage\}\}" duration="500" onchange="swiperChange"** sets the component attribute and event. **duration="500"** indicates that the duration of the swiping animation is 500 ms.
......@@ -28,7 +28,7 @@ The application home page displays air quality information of the current city.
- **onchange="swiperChange"** binds the change event of the **<swiper\>** component to the **swiperChange** function. The JavaScript code is as follows:
```
// Import the router module for page switch.
// Import the router module for page switching.
import router from'@system.router'
export default {
// Define parameters.
......@@ -106,7 +106,7 @@ The application home page displays air quality information of the current city.
- **index.css**
A **.css** file contains many classes. Each class defines the position, size, font, color, and background color of a component. Each child component is added to the parent component, which means that the style file of the parent component affects how the child component will be displayed.
A **.css** file contains many classes. Each class defines the position, size, font, color, and background color of a component. Each child component is added to its parent component, and the style file of the parent component affects how the child component will be displayed.
```
.pm25-value{
......@@ -162,10 +162,10 @@ The application home page displays air quality information of the current city.
- **index.js**
A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, the following features need to be implemented: Dynamic changes of the text content and progress bar color based on numbers, multiple languages, page switch, and animation playback.
A **.js** file is used to implement interaction logic of your application. In the **.js** file of the home page, the following features need to be implemented: dynamic changes of the text content and progress bar color based on numbers, multiple languages, page switching, and animation playback.
```
// Import the router module for page switch.
// Import the router module for page switching.
import router from'@system.router'
export default {
// Define parameters.
......
......@@ -2,11 +2,11 @@
1. Is there a global variable that can be accessed by all pages?
No such global variable is available for all pages.
There is no such a global variable.
2. How do I obtain DOM elements?
You can obtain DOM elements via the **ref** attribute. You can only use methods of the obtained elements and cannot change their attributes. The following figure shows an example.
You can obtain DOM elements via the **ref** attribute. You can use methods of the obtained elements but cannot change their attributes. The sample code is as follows:
```
<!--index.hml-->
......@@ -47,7 +47,7 @@
```
router.replace({
uri:'pages/detail/detail', // URI of the page to be redirected to.
uri:'pages/detail/detail', // URI of the page to switch to.
params:{transferData:this.data} // Data to be transferred. You need to define the data amount and name.
});
```
......@@ -66,7 +66,7 @@
5. Does the **<text\>** component support multiple lines?
Yes. You can use the Enter key to start a new line. Alternatively, you can choose not to set the height attribute of the text, and the component automatically starts a new line based on the content.
Yes. You can use the Enter key to start a new line. Alternatively, the component automatically starts a new line based on the content, without the need to set the height attribute of the text.
6. Why is a component not displayed?
......@@ -91,9 +91,9 @@
8. Why do not the **left** and **top** attributes take effect?
In addition to the root component, **left** and **top** attributes must work with the **<stack\>** component.
**left** and **top** attributes must work with the **<stack\>** component in addition to the root component.
9. Why does dynamic binding not take effect?
9. Why does not dynamic binding take effect?
The object or its attributes are not defined before dynamic binding.
......@@ -101,9 +101,9 @@
You can use the **<div\>** and **<stack\>** \(with **top** and **left** attributes\) components.
11. How do I set component transparency?
11. How do I set component opacity?
For the **<image\>** component, set the **opacity** attribute to adjust the transparency. For other components, set the alpha value \(in RGBA color channels\) of a component.
For the **<image\>** component, set the **opacity** attribute. For other components, set the alpha value \(in RGBA color channels\).
12. How do I display or hide a component?
......@@ -115,7 +115,7 @@
14. What are the precautions for event subscription?
Only one page exists when the application is running. Therefore, the **router.replace** function destroys the previous page and then creates a new one. For event subscription pages, the event should be subscribed every time a page is created, and unsubscribed before a page switch.
Only one page exists when the application is running. Therefore, the **router.replace** function destroys the previous page and then creates a new one. For event subscription pages, the event should be subscribed every time a page is created, and unsubscribed before page switching.
15. What are the precautions for using dynamic binding?
......
# Overview<a name="EN-US_TOPIC_0000001055367650"></a>
This section describes how to quickly set up a development environment for the basic head unit running on OpenHarmony and how to create, develop, and debug your application. This section uses an air quality application as an example.
This section describes how to quickly set up a development environment for the basic head unit running on OpenHarmony and how to create, develop, and debug your application. This section uses an air quality monitoring application \(AirQuality\) as an example.
## Display Effects<a name="section3997224182313"></a>
The application displays air quality information on three pages: **home** page fo overview, **detail** page, and **history** page. The following figure shows the application on the DevEco Studio simulator.
AirQuality displays air quality information on three pages: **home** page fo overview, **detail** page, and **history** page. The following figure shows AirQuality on the DevEco Studio simulator.
**Figure 1** Display effect of the air quality application<a name="fig97934104482"></a>
**Figure 1** Display effect of the application<a name="fig97934104482"></a>
![](figures/video_2020-07-25_173141.gif)
......
......@@ -274,7 +274,7 @@ None
ostringstream ss("Capture_");
ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg";
ofstream pic("/tmp/" + ss.str(), ofstream::out | ofstream::trunc);
ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc);
cout << "write " << size << " bytes" << endl;
pic.write(p, size);
cout << "Saving picture end" << endl;
......
......@@ -274,7 +274,7 @@ None
ostringstream ss("Capture_");
ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg";
ofstream pic("/tmp/" + ss.str(), ofstream::out | ofstream::trunc);
ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc);
cout << "write " << size << " bytes" << endl;
pic.write(p, size);
cout << "Saving picture end" << endl;
......
......@@ -6,5 +6,21 @@ Set up the environment by performing operations provided in **Environment Setup
## Creating a Project<a name="section1456035192720"></a>
For details, see section **Creating a Project** in the [DevEco Studio User Guide](https://developer.harmonyos.com/en/docs/documentation/doc-guides/tools_overview-0000001053582387).
The DevEco Studio provides only basic development functions. GUI preview and code commissioning will be provided in the next version.
Perform the following steps to create a project. Currently, projects of the **smartVision** type cannot be created directly.
1. Start the DevEco Studio, choose **File** \> **Project** and select **Lite Wearable** for **Device** and **Empty Feature Ability** for **Template**.
**Figure 1** Selecting project template<a name="fig1111842916140"></a>
![](figures/selecting-project-template.png "selecting-project-template")
2. After the creation is successful, modify the **config.json** file in **entry** \> **src** \> **main**.
1. Change the value of **"deviceType"** to **"smartVision"**.
2. Add the **"visible"** attribute to the **"abilities"** array and set the attribute value to **true**.
**Figure 2** Modifying the template<a name="fig654614531515"></a>
![](figures/modifying-the-template.png "modifying-the-template")
......@@ -6,7 +6,7 @@ Use the camera module APIs to generate and play video streams.
## Available APIs<a name="en-us_topic_0000001051930577_section125479541744"></a>
For details, see [Available APIs](photographing-3.md#en-us_topic_0000001052170554_section56549532016).
For details, see the available APIs described in development guidelines on photographing.
## Limitations and Constraints<a name="en-us_topic_0000001051930577_section1165911177314"></a>
......@@ -14,7 +14,7 @@ None
## How to Develop<a name="en-us_topic_0000001051930577_section34171333656"></a>
1. Perform step 1 through step 4 provided in [Development Guidelines on Photographing](photographing-3.md#EN-US_TOPIC_0000001054915940).
1. Perform step 1 through step 4 described in development guidelines on photographing.
2. Set the preview area.
```
......
# Running on the Device<a name="EN-US_TOPIC_0000001054809161"></a>
For details about the development board, compilation, burning, and image running process, see [Getting Started with Hi3516](../quick-start/introduction-to-the-hi3516-development-board.md). After running the image and the system is started normally, perform the following steps:
For details about the development board, compilation, burning, and image running process, see [Getting Started with Hi3516](../quick-start/introduction-to-the-hi3516-development-board.md). After image running is executed and the system is started normally, perform the following steps to install or uninstall the third-party application:
1. Install the third-party application for the debug version only.
1. Store the unsigned application installation package and installation tool compiled by the IDE in an SD card. \(IP camera applications currently do not support signature.\) The installation tool is in **idev\_tools** in the directory where the image file is generated.
2. Run the **./sdcard/dev\_tools/bin/bm set -s disable** command to disable signature verification.
3. Run the **./sdcard/dev\_tools/bin/bm install -p /sdcard/airquality.hap** command to install the application.
Store the application installation package \(with the **debug** signature\) and installation tool \(**dev\_tools** in the directory where the image file is generated\) in an SD card. The installation procedure is as follows:
The **dev\_tools** directory stores the installation tool, and **airquality.hap** is the application installation package.
1. Run the **./sdcard/dev\_tools/bin/bm set -d enable** command to enable the debugging signature.
2. Run the **./sdcard/dev\_tools/bin/bm install -p /sdcard/airquality.hap** command to install the application. The **dev\_tools** directory stores the installation tool, and **airquality.hap** is the application installation package.
3. After the application is installed, touch the application icon on the home screen to start the application.
4. After the application is installed, touch the application icon on the home screen to start the application.
**Figure 1** Home screen<a name="fig146361926155516"></a>
![](figures/home-screen.png "home-screen")
2. Uninstall the application.
5. \(Optional\) Uninstall the application.
Touch and hold the application icon on the home screen, and touch the uninstall button in the displayed menu.
......
# Use Case<a name="EN-US_TOPIC_0000001055686082"></a>
- For details about the development board, compilation, burning, and image running process, see [Getting Started with Hi3518](../quick-start/introduction-to-the-hi3518-development-board.md). The compilation results include that of the **camera\_sample** program.
- For details about the development board, compilation, burning, and image running process, see [Getting Started with Hi3518](en-us_topic_0000001054261054.md). The compilation results include that of the **camera\_sample** program.
- The sample code for camera development is stored in **applications/sample/camera/media/camera\_sample.cpp**.
>![](public_sys-resources/icon-notice.gif) **NOTICE:**
......
......@@ -6,7 +6,7 @@ Use the camera module APIs to capture video streams.
## Available APIs<a name="en-us_topic_0000001051451869_section125479541744"></a>
For details, see [接口说明](en-us_topic_0000001052170554.md#section56549532016).
For details, see the available APIs described in development guidelines on photographing.
## Limitations and Constraints<a name="en-us_topic_0000001051451869_section1165911177314"></a>
......@@ -14,7 +14,7 @@ None
## How to Develop<a name="en-us_topic_0000001051451869_section1196016315516"></a>
1. Perform step 1 through step 4 provided in [拍照开发指导](en-us_topic_0000001052170554.md).
1. Perform step 1 through step 4 described in development guidelines on photographing.
2. Obtain the **FrameConfig** instance for audio recording.
```
......
......@@ -6,7 +6,7 @@ Use the camera module APIs to capture video streams.
## Available APIs<a name="en-us_topic_0000001051451869_section125479541744"></a>
For details, see [Available APIs](photographing.md#en-us_topic_0000001052170554_section56549532016).
For details, see the available APIs described in development guidelines on photographing.
## Limitations and Constraints<a name="en-us_topic_0000001051451869_section1165911177314"></a>
......@@ -14,7 +14,7 @@ None
## How to Develop<a name="en-us_topic_0000001051451869_section1196016315516"></a>
1. Perform step 1 through step 4 provided in [Development Guidelines on Photographing](photographing.md#EN-US_TOPIC_0000001054954859).
1. Perform step 1 through step 4 described in development guidelines on photographing.
2. Obtain the **FrameConfig** instance for audio recording.
```
......
# Kernel Usage Guidelines
- [OpenHarmony Basic Kernel Functions](openharmony-basic-kernel-functions.md)
- [OpenHarmony Lite Kernel Basic Functions](openharmony-lite-kernel-basic-functions.md)
- [Process](process.md)
- [Thread](thread.md)
- [Memory](memory.md)
- [Network](network.md)
- [Kernel File System](kernel-file-system.md)
- [OpenHarmony Lite Kernel File System](openharmony-lite-kernel-file-system.md)
- [VFS](vfs.md)
- [NFS](nfs.md)
- [RAMFS](ramfs.md)
......
......@@ -12,7 +12,7 @@ The OpenHarmony kernel supports multiple partitions on the hard disk. A FAT file
## Important Notes<a name="section781233610116"></a>
- A maximum of 256 FATFS files or folders that can be opened simultaneously.
- A maximum of 512 FATFS files or folders that can be opened simultaneously.
- After a file is opened in writable mode, the file cannot be opened again before it is closed. To open a file for multiple times, the read-only attribute can be used only. If a file is opened for a long time and is not closed, data loss will occur. The file can be saved only after being closed.
......
# OpenHarmony Lite Kernel Basic Functions<a name="EN-US_TOPIC_0000001054329761"></a>
- **[Process](process.md)**
- **[Thread](thread.md)**
- **[Memory](memory.md)**
- **[Network](network.md)**
# OpenHarmony Lite Kernel File System<a name="EN-US_TOPIC_0000001051611726"></a>
The OpenHarmony lite kernel supports the following file systems: Virtual File System \(VFS\), Network File System \(NFS\), RAM File System \(RAMFS\), File Allocation Table \(FAT\), and Journalling Flash File System Version 2 \(JFFS2\).
The table below describes the functions of these file systems.
**Table 1** File system functions
<a name="table6330194819415"></a>
<table><thead align="left"><tr id="row6331184864111"><th class="cellrowborder" valign="top" width="11.559999999999999%" id="mcps1.2.3.1.1"><p id="p17644161411438"><a name="p17644161411438"></a><a name="p17644161411438"></a>File System</p>
</th>
<th class="cellrowborder" valign="top" width="88.44%" id="mcps1.2.3.1.2"><p id="p116441414184312"><a name="p116441414184312"></a><a name="p116441414184312"></a>Function</p>
</th>
</tr>
</thead>
<tbody><tr id="row371213562318"><td class="cellrowborder" valign="top" width="11.559999999999999%" headers="mcps1.2.3.1.1 "><p id="p37130569316"><a name="p37130569316"></a><a name="p37130569316"></a>VFS</p>
</td>
<td class="cellrowborder" valign="top" width="88.44%" headers="mcps1.2.3.1.2 "><p id="p1771335615316"><a name="p1771335615316"></a><a name="p1771335615316"></a>In essence, VFS is not a real file system. It is an abstract layer on top of a heterogeneous file system and provides you with a unified Unix-like file operation interface.</p>
</td>
</tr>
<tr id="row189255844219"><td class="cellrowborder" valign="top" width="11.559999999999999%" headers="mcps1.2.3.1.1 "><p id="p1564481494319"><a name="p1564481494319"></a><a name="p1564481494319"></a>NFS</p>
</td>
<td class="cellrowborder" valign="top" width="88.44%" headers="mcps1.2.3.1.2 "><p id="p764561414434"><a name="p764561414434"></a><a name="p764561414434"></a>NFS allows you to share files across hosts and OSs over a network.</p>
</td>
</tr>
<tr id="row17332194820411"><td class="cellrowborder" valign="top" width="11.559999999999999%" headers="mcps1.2.3.1.1 "><p id="p2064561415435"><a name="p2064561415435"></a><a name="p2064561415435"></a>RAMFS</p>
</td>
<td class="cellrowborder" valign="top" width="88.44%" headers="mcps1.2.3.1.2 "><p id="p12646614204320"><a name="p12646614204320"></a><a name="p12646614204320"></a>RAMFS is a RAM-based file system. All files are stored in the RAM, and file read/write operations are performed in the RAM, which reduces the read/write loss of the memory and improves the data read/write speed. It provides a RAM-based storage buffer for dynamic file systems.</p>
</td>
</tr>
<tr id="row16332174894116"><td class="cellrowborder" valign="top" width="11.559999999999999%" headers="mcps1.2.3.1.1 "><p id="p1864571410433"><a name="p1864571410433"></a><a name="p1864571410433"></a>FAT</p>
</td>
<td class="cellrowborder" valign="top" width="88.44%" headers="mcps1.2.3.1.2 "><p id="p364511141434"><a name="p364511141434"></a><a name="p364511141434"></a>There are FAT12, FAT16, and FAT32. FAT is often used on removable storage media (such as USB flash drives, SD cards, and portable hard disks) to provide better compatibility between devices and desktop systems such as Windows and Linux.</p>
</td>
</tr>
<tr id="row1880218157414"><td class="cellrowborder" valign="top" width="11.559999999999999%" headers="mcps1.2.3.1.1 "><p id="p19645814144312"><a name="p19645814144312"></a><a name="p19645814144312"></a>JFFS2</p>
</td>
<td class="cellrowborder" valign="top" width="88.44%" headers="mcps1.2.3.1.2 "><p id="p8645161454314"><a name="p8645161454314"></a><a name="p8645161454314"></a>JFFS2 is a journal-type file system implemented on Memory Technology Devices (MTDs). It is mainly used to manage files of the NOR flash memory. JFFS2 used in the <span id="text181481059803"><a name="text181481059803"></a><a name="text181481059803"></a>OpenHarmony</span> kernel supports multiple partitions.</p>
</td>
</tr>
</tbody>
</table>
- **[VFS](vfs.md)**
- **[NFS](nfs.md)**
- **[RAMFS](ramfs.md)**
- **[FAT](fat.md)**
- **[JFFS2](jffs2.md)**
......@@ -4,7 +4,7 @@ This section describes how to modify, compile, burn, and run the first program,
## Acquiring Source Code<a name="section215953714245"></a>
You need to acquire Hi3516 source code \([http://tools.harmonyos.com/mirrors/os/1.0/ipcamera\_hi3516dv300-1.0.tar.gz](http://tools.harmonyos.com/mirrors/os/1.0/ipcamera_hi3516dv300-1.0.tar.gz) or [https://mirrors.huaweicloud.com/harmonyos/1.0/ipcamera\_hi3516dv300-1.0.tar.gz](https://mirrors.huaweicloud.com/harmonyos/1.0/ipcamera_hi3516dv300-1.0.tar.gz)\) and download it on a Linux server. For more obtaining methods, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
You need to acquire [Hi3516 source code](http://tools.harmonyos.com/mirrors/os/1.0/code-1.0.tar.gz) and download it on a Linux server. For more obtaining methods, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
## Modifying a Program<a name="s8efc1952ebfe4d1ea717182e108c29bb"></a>
......
......@@ -4,7 +4,7 @@ This section describes how to modify, compile, burn, and run the first program o
## Acquiring Source Code<a name="section1726092873119"></a>
You need to acquire Hi3518 source code \([http://tools.harmonyos.com/mirrors/os/1.0/ipcamera\_hi3518ev300-1.0.tar.gz](http://tools.harmonyos.com/mirrors/os/1.0/ipcamera_hi3518ev300-1.0.tar.gz) or [https://mirrors.huaweicloud.com/harmonyos/1.0/ipcamera\_hi3518ev300-1.0.tar.gz](https://mirrors.huaweicloud.com/harmonyos/1.0/ipcamera_hi3518ev300-1.0.tar.gz)\) and download it on a Linux server. For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
You need to acquire [Hi3518 source code](http://tools.harmonyos.com/mirrors/os/1.0/code-1.0.tar.gz) and download it on a Linux server. For details, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
## Modifying a Program<a name="s8efc1952ebfe4d1ea717182e108c29bb"></a>
......@@ -115,5 +115,5 @@ Burn images to the Hi3518EV300 board over the serial port.
## Follow-up Learning<a name="section9712145420182"></a>
Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](../guide/camera-control.md).
Congratulations! You have finished all steps! You are advised to go on learning how to develop [Cameras with a Screen](en-us_topic_0000001055366100.md).
......@@ -4,7 +4,7 @@ This example shows how to use attention \(AT\) commands to complete WLAN module
## Acquiring Source Code<a name="section1545225464016"></a>
You need to acquire Hi3861 source code \([Site 1](http://tools.harmonyos.com/mirrors/os/1.0/wifiiot-1.0.tar.gz) or [Site 2](https://mirrors.huaweicloud.com/harmonyos/1.0/wifiiot-1.0.tar.gz)\) and download it on a Linux server. For more obtaining methods, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
You need to acquire [Hi3861 source code](http://tools.harmonyos.com/mirrors/os/1.0/code-1.0.tar.gz) and download it on a Linux server. For more obtaining methods, see [Source Code Acquisition](../get-code/source-code-acquisition.md).
## Compiling Source Code<a name="section1736014117148"></a>
......
此差异已折叠。
# Compilation and Building Subsystem<a name="EN-US_TOPIC_0000001052340730"></a>
## Overview<a name="section11660541593"></a>
The compilation and building subsystem provides a compilation and building framework based on GN and Ninja. Using this subsystem, you can perform the following operations:
1. Build products with different chip platforms. For example, you can build IP camera products on the Hi3518EV300 and Hi3516DV300 development boards and WLAN module product on the Hi3861 development board.
2. Build a customized product generated by HPM configurations.
## Directory Structure<a name="section1464106163817"></a>
```
build/lite # Compile and build a primary directory.
├── config # Compile related configuration items.
│ ├── boards # Define variables related to a development board, including its name, target architecture, and target CPU.
│ ├── component # Define templates related to OpenHarmony components, including static libraries, dynamic libraries, extended components, and simulator libraries.
│ ├── kernel # Define compilation variables of OpenHarmony kernel and configuration parameters.
│ └── subsystem # OpenHarmony subsystem lists
├── ndk # Define NDK-related compilation scripts and configuration parameters.
├── platform # Platform-related configuration files
│ ├── hi3516dv300_liteos_a # HI3516DV300 and LiteOS_A platforms, including the platform full configuration table and boot file.
│ ├── hi3518ev300_liteos_a # HI3518EV300 and LiteOS_A platforms, including the platform full configuration table and boot file.
│ └── hi3861v100_liteos_riscv # HI3861V100 and LiteOS_RISCV platforms, including the platform full configuration table and boot file.
├── product # Product full configuration table, including the configuration unit, subsystem list, and compiler
├── toolchain # Compilation toolchain, including the compiler path, compilation options, and link options.
└── tools # Tools on which compilation and building depend, including mkfs.
```
## Constraints<a name="section1718733212019"></a>
You must preinstall GN and Ninja and add them to environment variables.
## Usage<a name="section641210360552"></a>
- Compile an existing product.
```
# Compile the WLAN platform.
python build.py wifiiot
# Compile the IP camera based on Hi3518EV300.
python build.py ipcamera_hi3518ev300
# Compile the IP camera based on Hi3516DV300.
python build.py ipcamera_hi3516dv300
```
- Compile components.
This section uses a customized component as an example to describe how to compile a component, a library, and an executable file.
The example component consists of two functions: **feature1** and **feature2**. **feature1** is a dynamic library, and **feature2** is an executable file.
The complete directory structure of the example component is as follows:
```
example # Customized component
├── BUILD.gn # GN script of a customized component. BUILD.gn is a fixed name.
├── feature1 # Customized unit 1
│ ├── BUILD.gn # GN script of the customized unit 1. BUILD.gn is a fixed name.
│ ├── include # Header file folder
│ │ └── helloworld1.h # Header file 1
│ └── src # Source file folder
│ └── helloworld1.c # Source file 1
├── feature2 # Customized unit 2
│ ├── BUILD.gn # GN script of the customized unit 2. BUILD.gn is a fixed name.
│ ├── include # Header file folder
│ │ └── helloworld2.h # Header file 2
│ └── src # Source file folder
│ └── helloworld2.c # Source file 2
├── build.sh # build.sh script of the customized component, which is optional
└── Makefile # Makefile script of the customized component, which is optional
```
Step 1: Compile the **BUILD.gn** script of a dynamic library in the **example/feature1** directory.
The **lite\_library** template can be used to compile dynamic and static libraries. The following is an example:
```
# Example of compiling the helloworld dynamic library
# Build.gn file of helloworld
lite_library("helloworld_lib") {
target_type = "shared_library" # Compile a dynamic library.
#target_type = "static_library" # Compile a static library.
sources = [
"src/helloworld1.c"
]
include_dirs = [
"include",
"../feature2_example/include" # If feature2_example is required, add it to this include.
]
}
```
Step 2: Compile the **BUILD.gn** script of an executable file in the **example/feature2** directory.
The executable template provided by GN can be used to compile an executable file. The following is an example:
```
# Compile the executable .bin file.
executable("hello_world_bin") {
sources = [
"src/helloworld.c"
]
include_dirs = [
"include",
#"../feature2_example/include" # If feature2_example is required, add it to this include.
]
# If feature1_example is required, add it to this deps.
#deps = [
# "../feature1_example:helloworld1"
#]
}
```
Step 3: Compile the **BUILD.gn** script of a component in the **example/BUILD.gn** directory.
```
import("//build/lite/config/component/lite_component.gni")
# Use the BUILD.gn script to compile the entire project.
lite_component("example_gn") {
features = [
"feature_example1:helloworld_lib",
"feature_example2:hello_world_bin",
]
}
# Integrate the built-in build.sh or Makefile project and use the gn script to call the hybrid compilation.
build_ext_component("example_mk") {
exec_path = rebase_path(rebase_path(".", root_build_dir))
outdir = rebase_path(get_path_info(".", "out_dir"))
prebuilts = "sh build.sh"
command = "make clean && make"
}
```
- Available compilation and building variables
The variables that can be referenced globally are defined in **//build/lite/ohos\_var.gni**.
[Table 1](#table3296103714372) describes the common variables of users.
**Table 1**
<a name="table3296103714372"></a>
<table><thead align="left"><tr id="row529623712377"><th class="cellrowborder" valign="top" width="16.89%" id="mcps1.2.4.1.1"><p id="p1629723723717"><a name="p1629723723717"></a><a name="p1629723723717"></a>Variable</p>
</th>
<th class="cellrowborder" valign="top" width="32.98%" id="mcps1.2.4.1.2"><p id="p13297137163720"><a name="p13297137163720"></a><a name="p13297137163720"></a>Value Range</p>
</th>
<th class="cellrowborder" valign="top" width="50.129999999999995%" id="mcps1.2.4.1.3"><p id="p1423425618374"><a name="p1423425618374"></a><a name="p1423425618374"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row14297437193710"><td class="cellrowborder" valign="top" width="16.89%" headers="mcps1.2.4.1.1 "><p id="p62978371374"><a name="p62978371374"></a><a name="p62978371374"></a>ohos_kernel_type</p>
</td>
<td class="cellrowborder" valign="top" width="32.98%" headers="mcps1.2.4.1.2 "><p id="p1229716378376"><a name="p1229716378376"></a><a name="p1229716378376"></a>"liteos_a", "liteos_riscv"</p>
</td>
<td class="cellrowborder" valign="top" width="50.129999999999995%" headers="mcps1.2.4.1.3 "><p id="p17234105673718"><a name="p17234105673718"></a><a name="p17234105673718"></a>Kernel type</p>
</td>
</tr>
<tr id="row8722028184617"><td class="cellrowborder" valign="top" width="16.89%" headers="mcps1.2.4.1.1 "><p id="p773182820463"><a name="p773182820463"></a><a name="p773182820463"></a>board_name</p>
</td>
<td class="cellrowborder" valign="top" width="32.98%" headers="mcps1.2.4.1.2 "><p id="p20731128124612"><a name="p20731128124612"></a><a name="p20731128124612"></a>"hi3516dv300", "hi3518ev300", "hi3861v100"</p>
</td>
<td class="cellrowborder" valign="top" width="50.129999999999995%" headers="mcps1.2.4.1.3 "><p id="p2737281461"><a name="p2737281461"></a><a name="p2737281461"></a>Development board type</p>
</td>
</tr>
<tr id="row1813718203473"><td class="cellrowborder" valign="top" width="16.89%" headers="mcps1.2.4.1.1 "><p id="p1813715200473"><a name="p1813715200473"></a><a name="p1813715200473"></a>ohos_build_compiler</p>
</td>
<td class="cellrowborder" valign="top" width="32.98%" headers="mcps1.2.4.1.2 "><p id="p1913713206476"><a name="p1913713206476"></a><a name="p1913713206476"></a>"gcc", "clang"</p>
</td>
<td class="cellrowborder" valign="top" width="50.129999999999995%" headers="mcps1.2.4.1.3 "><p id="p013732013476"><a name="p013732013476"></a><a name="p013732013476"></a>Compilation toolchain type</p>
</td>
</tr>
</tbody>
</table>
Example: Ohos\_kernel\_type usage, component\_example/feature2\_example/BUILD.gn
```
lite_library("helloworld") {
if (ohos_kernel_type == "liteos_a") {
target_type = "shared_library"
}
else if (ohos_kernel_type == "liteos_riscv") {
target_type = "static_library"
}
sources = [
"src/helloworld1.c"
]
include_dirs = [
"include"
]
}
```
- Solution
After a template is downloaded from HPM, the customized full template is stored in the **//build/lite/product** directory.
For example, ipcamera\_hi3516dv300.json. This file that contains the configurations of all customized subsystems and components is read.
- Compilation output
All files generated during compilation are stored in the **out** directory.
In the directory where the code is located, run **python build.py wifiiot**. After the WLAN compilation is complete, the following results are generated.
```
out/
└── wifiiot # Product name
├── args.gn # Customized variable for gn compilation
├── build.log # Compilation log
├── build.ninja
├── build.ninja.d
├── gen
├── Hi3861_boot_signed_B.bin # Signed bootloader backup file
├── Hi3861_boot_signed.bin # Signed bootloader file
├── Hi3861_loader_signed.bin # Loading file used by the burning tool
├── Hi3861_wifiiot_app_allinone.bin # Production line tool burning file, including the independent burning program and loader program
├── Hi3861_wifiiot_app.asm # Kernel asm file
├── Hi3861_wifiiot_app_burn.bin # Burning file
├── Hi3861_wifiiot_app_flash_boot_ota.bin # Flash boot upgrade file
├── Hi3861_wifiiot_app.map # Kernel map file
├── Hi3861_wifiiot_app_ota.bin # Kernel upgrade file
├── Hi3861_wifiiot_app.out # Kernel output file
├── Hi3861_wifiiot_app_vercfg.bin # The boot and kernel version numbers are configured for secure boot to prevent version rollback.
├── libs # Library folder
├── NOTICE_FILE
├── obj
├── suites
└── toolchain.ninja
Note: You are advised to use Hi3861_wifiiot_app_allinone.bin to burn files.
```
Run **python build.py ipcamera\_hi3518ev300**. After IP camera\_HI3518EV300 is compiled, the following result is generated \(the same as IP camera\_HI3516DV300\).
```
out/
└── ipcamera_hi3518ev300 # Product name
├── args.gn # Customized variable for gn compilation
├── bin # Link to the folder where the bin file is located.
├── bm_tool.map # map file
├── build.log # Compilation log
├── build.ninja
├── build.ninja.d
├── bundle_daemon_tool.map # map file
├── data # Configuration file of underlying resources on which the media camera depends.
├── dev_tools # R&D self-testing
├── foundation.map # map file
├── gen
├── libaudio_api.so
├── libs # Library files contained in an image
├── liteos.bin # bin file of the LiteOS basic kernel
├── media_server.map # map file
├── NOTICE_FILE
├── obj # Binary file, which is the compilation result folder
├── OHOS_Image # .bin file for the LiteOS package without strip
├── OHOS_Image.asm # Assembly code
├── OHOS_Image.bin # Burning the .bin file for the LiteOS package
├── OHOS_Image.map # map file
├── rootfs.img # Compiled library and app image
├── rootfs.tar # Compress rootfs.tar.
├── suites # xts compilation result
├── test # Test case compilation result
├── toolchain.ninja
├── userfs # User-readable and writable partition
├── userfs.img # User-readable and writable partition in .img format, corresponding to the /storage directory after startup
└── vendor # Firmware file and configuration file of the chip
```
## Repositories Involved<a name="section6299103515474"></a>
build\_lite
此差异已折叠。
# Distributed Communication Subsystem<a name="EN-US_TOPIC_0000001051344287"></a>
## Overview<a name="section11660541593"></a>
The use of different communication modes \(such as USB, WLAN, and Bluetooth\) varies greatly and is complex. In addition, the convergence, sharing, and conflicts between communication links cannot be resolved, and communication security is difficult to guarantee. The distributed communication subsystem manages unified distributed communication between near-field devices and provides device discovery and data transmission APIs that apply to all links. Currently, the following features are available:
- Service publishing: After a service is published, peripheral devices can discover and use it.
- Data transmission: A session is established based on the service name and device ID to transmit data between services.
- Security: Communication data is encrypted.
You can use APIs of the distributed communication subsystem to implement fast and secure communication between devices without caring about management of communication details, thereby achieving cross-platform development.
## Directory Structure<a name="section1464106163817"></a>
The following figure shows the softbus\_lite source code directory structure.
**Table 1** softbus\_lite source code directory structure
<a name="table1843451445317"></a>
<table><thead align="left"><tr id="row16552191445314"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="p75521114125314"><a name="p75521114125314"></a><a name="p75521114125314"></a>Name</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="p2055231419539"><a name="p2055231419539"></a><a name="p2055231419539"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row15552151465314"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p255221425316"><a name="p255221425316"></a><a name="p255221425316"></a>authmanager</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p11552114135313"><a name="p11552114135313"></a><a name="p11552114135313"></a>Provides the device authentication mechanism and manages device knowledge libraries.</p>
</td>
</tr>
<tr id="row1755251416537"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p455231495317"><a name="p455231495317"></a><a name="p455231495317"></a>discovery</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p15531214115319"><a name="p15531214115319"></a><a name="p15531214115319"></a>Provides a device discovery mechanism that is based on the Constrained Application Protocol (CoAP).</p>
</td>
</tr>
<tr id="row155534148533"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p1252015524711"><a name="p1252015524711"></a><a name="p1252015524711"></a>trans_service</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p1752055220713"><a name="p1752055220713"></a><a name="p1752055220713"></a>Provides authentication and transmission channels.</p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section1718733212019"></a>
- Language: C
- Networking: Devices must be in the same LAN.
## Usage<a name="section167037358130"></a>
1. Discover devices.
When using device discovery, ensure that the device to perform a discovery and the discovered device are in the same LAN and the devices can receive packets from each other.
a. After a device sends a discovery request, it uses CoAP to send a broadcast packet in the LAN. The following figure shows the request packet.
![](figures/1.png)
b. The discovered device uses the **PublishService** API to publish services. After receiving the broadcast packet, the device sends a CoAP unicast packet to the device that performs the discovery. The following figure shows the packet example.
![](figures/2.png)
c. After receiving the packet, the device that performs the discovery updates device information.
The following is an example of how to use device discovery:
```
// Declare the callback function.
void onSuccess(int publishId)
{
printf("public success,publishId = %d\r\n", publishId);
}
void onFail(int publishId, PublishFailReason reason)
{
printf("publish failed, publishId = %d, reason = %d\r\n", publishId, reason);
}
// Publish services.
PublishInfo info = {0};
IPublishCallback cb = {0};
cb.onPublishSuccess = onSuccess;
cb.onPublishFail = onFail;
char a[] = "456";
info.capabilityData = a;
info.capability = "ddmpCapability";
info.dataLen = strlen("456");
info.medium = 2;
info.publishId = 1;
PublishService("cxx", &info, &cb);
```
2. Transmit data.
The soft bus provides unified session-based transmission. Services can receive and send data or obtain basic attributes through **sessionId**. Currently, services can determine whether to accept a received session based on the service requirements and session attributes. Currently, sessions cannot be enabled.
The sample code for data transmission is as follows:
```
// Define the service name, session name, and related callback.
const char *g_pkgName = "BUSINESS_NAME";
const char *g_sessionName = "SESSION_NAME";
struct ISessionListener * g_sessionCallback= NULL;
// Implement the callback: After receiving data sent by the peer end using SendBytes, return a fixed message.
void OnBytesReceivedTest(int sessionId, const void* data, unsigned int dataLen)
{
printf("OnBytesReceivedTest\n");
printf("Recv Data: %s\n", (char *)data);
printf("Recv Data dataLen: %d\n", dataLen);
char *testSendData = "Hello World, Hello!";
SendBytes(sessionId, testSendData, strlen(testSendData));
return;
}
// Implement the callback: Perform relevant operations after the session is closed, for example, releasing service resources related to the current session. The session does not need to be released by the service.
void OnSessionClosedEventTest(int sessionId)
{
printf("Close session successfully, sessionId=%d\n", sessionId);
}
// Implement the callback: Perform relevant operations after a session is opened. The return value 0 means to accept the session, and other values mean to reject the session. In the following example, only sessions with the same name from other devices are accepted.
int OnSessionOpenedEventTest(int sessionId)
{
if (strcmp(GetPeerSessionName(sessionId), SESSION_NAME) != 0) {
printf("Reject the session which name is different from mine, sessionId=%d\n", sessionId);
return -1;
}
printf("Open session successfully, sessionId=%d\n", sessionId);
return 0;
}
// Register the service session service and its callbacks with the soft bus.
int StartSessionServer()
{
if (g_sessionCallback != NULL) {
g_sessionCallback = (struct ISessionListener*)malloc(sizeof(struct ISessionListener));
}
if (g_sessionCallback == NULL) {
printf("Failed to malloc g_sessionCallback!\n");
return -1;
}
g_sessionCallback->onBytesReceived = OnBytesReceivedTest;
g_sessionCallback->onSessionOpened = OnSessionOpenedEventTest;
g_sessionCallback->onSessionClosed = OnSessionClosedEventTest;
int ret = CreateSessionServer(g_pkgName, g_sessionName, g_sessionCallback);
if (ret < 0) {
printf("Failed to create session server!\n");
free(g_sessionCallback);
g_sessionCallback = NULL;
}
return ret;
}
// Delete the service session service and its callbacks from the soft bus.
void StopSessionServer()
{
int ret = RemoveSessionServer(g_pkgName, g_sessionName);
if (ret < 0) {
printf("Failed to remove session server!\n");
return;
}
if (g_sessionCallback != NULL) {
free(g_sessionCallback);
g_sessionCallback = NULL;
}
}
```
## Repositories Involved<a name="section4499619123117"></a>
communication\_frameworks\_wifi\_lite
communication\_frameworks\_ipc\_lite
communication\_hals\_wifi\_lite
communication\_interfaces\_kits\_ipc\_lite
communication\_interfaces\_kits\_softbuskit\_lite
communication\_interfaces\_kits\_wifi\_lite
communication\_services\_softbus\_lite
# Distributed Scheduler<a name="EN-US_TOPIC_0000001051983009"></a>
## Overview<a name="section11660541593"></a>
The Distributed Scheduler sets up a distributed service platform in OpenHarmony by using a proxy between the primary and secondary devices. With the distributed scheduler, the primary device \(OpenHarmony-powered smart TV\) can start a Feature Ability \(FA\) deployed on the secondary device \(a memory-constrained OpenHarmony device such as a lite wearable\). The following figure shows the components of the Distributed Scheduler.
![](figures/en-us_image_0000001055199362.png)
## Directory Structure<a name="section1464106163817"></a>
The following table describes the directory structure of the Distributed Scheduler.
**Table 1** Directory structure of the major source code
<a name="table43531856201716"></a>
<table><thead align="left"><tr id="row20416556201718"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="p10416456121716"><a name="p10416456121716"></a><a name="p10416456121716"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="p1841645631717"><a name="p1841645631717"></a><a name="p1841645631717"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row64161056151718"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p9416656181720"><a name="p9416656181720"></a><a name="p9416656181720"></a>dtbschedmgr_lite</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p541645611177"><a name="p541645611177"></a><a name="p541645611177"></a>Implementation logic of the Distributed Scheduler</p>
</td>
</tr>
<tr id="row104169564177"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p17416125614179"><a name="p17416125614179"></a><a name="p17416125614179"></a>safwk_lite</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p04163569170"><a name="p04163569170"></a><a name="p04163569170"></a>Implementation logic of system service processes</p>
</td>
</tr>
<tr id="row04161056121719"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p13416165621713"><a name="p13416165621713"></a><a name="p13416165621713"></a>samgr_lite</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p13417125611175"><a name="p13417125611175"></a><a name="p13417125611175"></a>Implementation logic of local service management</p>
</td>
</tr>
</tbody>
</table>
The source code directory structure of the Distributed Scheduler is as follows:
```
├── BUILD.gn
├── include
│ ├── distributed_schedule_service.h # Header file for the open APIs provided by the Distributed Scheduler
│ ├── dmslite_check_remote_permission.h # Header file for the permission management module of the Distributed Scheduler
│ ├── dmslite_famgr.h # Header file for the FA management module of the Distributed Scheduler
│ ├── dmslite_inner_common.h # Header file for the service files of the Distributed Scheduler
│ ├── dmslite.h # Header file for the implementation of the Distributed Scheduler
│ ├── dmslite_log.h # Header file for the log module
│ ├── dmslite_msg_parser.h # Header file for communication data deserialization
│ ├── dmslite_tlv_common.h # Header file for the TLV data parsing module
│ └── dmslite_session.h # Header file for enabling cross-device communication
├── README.md
├── LICENSE
├── source
├── distributed_schedule_service.c
├── dmslite.c
├── dmslite_check_remote_permission.c
├── dmslite_famgr.c
├── dmslite_msg_parser.c
├── dmslite_tlv_common.c
└── dmslite_session.c
```
## Constraints<a name="section1718733212019"></a>
- Language: C
- Networking: Devices must be on the same LAN.
- Operating system: OpenHarmony
**Limitations and constraints on remote startup**:
- Only FAs can be started remotely. Remote startup is unavailable to abilities using the Service template.
- Before the remote startup, ensure that the primary and secondary devices are on the same network segment and can ping each other. Otherwise, the remote startup fails.
## Usage<a name="section10729231131110"></a>
**Compiling the Distributed Scheduler**
The distributed scheduler uses some feature macros to customize the function code to be compiled on different platforms. The function code is stored in **build\\lite\\config\\subsystem\\distributedschedule\\**. The directory structure is as follows:
```
build/lite/config/subsystem/distributedschedule
├── BUILD.gn
```
Modify the **BUILD.gn** file when compiling code for different platforms. The following code snippet uses code compilation for the Hi3518EV300 and Hi3516DV300 development boards as an example:
```
zlite_subsystem("distributedschedule") {
subsystem_components = [
"//foundation/distributedschedule/services/samgr_lite:samgr",
]
if (board_name == "hi3518ev300" || board_name == "hi3516dv300") {
subsystem_components += [
"//foundation/distributedschedule/services/safwk_lite:safwk_lite",
"//foundation/distributedschedule/services/dtbschedmgr_lite:dtbschedmgr", // Configure the distributed scheduler.
]
}
}
```
**\* Primary device development** \(taking FA startup as an example\)
Create a **Want** instance. You should first create an **ElementName** object with **deviceId**, **bundleName**, and **abilityName** specified and add this object to the **Want** instance. Then, set the multi-device startup flag **Want.FLAG\_ABILITYSLICE\_MULTI\_DEVICE** to the **Want** instance to enable remote FA startup.
```
// Import related header files.
import ohos.aafwk.ability.Ability;
import ohos.aafwk.content.Want;
import ohos.bundle.ElementName;
// Start the remote FA on the secondary device.
Want want = new Want(); // Create a Want instance that encapsulates information about the remote FA to start.
ElementName name = new ElementName("remote_device_id", "com.huawei.remote_package_name", "remote_class_name");
want.setElement(name); // Add information about the target FA for startup to the Want instance.
want.setFlags(Want.FLAG_ABILITYSLICE_MULTI_DEVICE); // Set the multi-device startup flag. If this flag is not set, remote FA startup will be unavailable.
startAbility(want); // Start the specified FA based on the want parameter. If the name and type of the want parameter are different from those used in the IDE, use the parameter name and type in the IDE.
```
**\* Prerequisites**
**Networking between the primary and secondary devices**: Before the remote startup, ensure that the two devices are on the same network segment and can ping each other. Otherwise, the remote startup fails.
**FA installation on the secondary device**: Before the remote startup, ensure that the target FA has been installed on the secondary device.
**\* Execution** \(taking FA startup as an example\)
Call **startAbility** on the primary device \(smart TV\) to start the FA of the secondary device \(memory-constrained device such as a lite wearable\).
## Repositories Involved<a name="section176111311166"></a>
distributedschedule\_interfaces\_kits\_samgr\_lite
distributedschedule\_services\_dtbschedmgr\_lite
distributedschedule\_services\_safwk\_lite
# Driver Subsystem<a name="EN-US_TOPIC_0000001052619216"></a>
## Overview<a name="section11660541593"></a>
The OpenHarmony driver subsystem is constructed using the C object-oriented programming \(OOP\). It provides a unified driver platform through platform decoupling, kernel decoupling, and compatible kernels. This unified driver architecture platform is designed to provide a more precise and efficient development environment, where you develop a driver that can be deployed on different systems supporting HDF.
The OpenHarmony driver subsystem provides the following key features and capabilities to shorten the driver development period and make third-party device driver integration much easier:
- Flexible framework capabilities
Based on the traditional driver framework, the OpenHarmony driver subsystem builds flexible framework capabilities to deploy terminal products with the capacity ranging from hundreds KB to hundreds MB of memory.
- Standardized driver APIs
The OpenHarmony driver subsystem provides you with abundant and stable driver APIs, which are compatible with those of future-proof smartphones, tablets, smart TVs.
- Component-based driver models
The OpenHarmony driver subsystem supports component-based driver models. It provides more refined driver management to dismantle components, enabling you to focus on the interaction between the hardware and driver.
The subsystem also presets some template-based driver model components, such as the network device models.
- Normalized configuration GUIs
The OpenHarmony driver subsystem provides a unified configuration GUI and a cross-platform tool for configuration conversion and generation to implement seamless switchover across platforms.
You can use DevEco to manage driver projects, generate driver templates, and manage settings to make the development of OpenHarmony drivers easier.
## Architecture<a name="section101721227145613"></a>
The OpenHarmony driver framework adopts the primary/secondary mode and is developed based on the framework, model, competence library, and tool.
**Figure 1** Interaction between the driver and framework<a name="fig2213154653916"></a>
![](figures/en-us_image_0000001053805078.png)
- Driver framework stored in the **frameworks/core** directory
- Loads and starts drivers.
- Deploys and expands the driver framework flexibly through the object manager.
- Driver models stored in the **frameworks/model** directory
- Provides model-based driving capabilities, such as network device models.
- Driver capability library stored in the **frameworks/ability** directory
- Provides basic driver models, such as the I/O communication model.
- Driver tools stored in the **frameworks\\tools** directory
- Provides tools for HDI API conversion, and driver configuration and driver compilation.
- Driver APIs stored in the **lite\\hdi** directory
- Provides normalized driver APIs.
- Support stored in the **frameworks/support** directory
- Provides platform driver APIs and system APIs with normalized abstraction capabilities.
## Directory Structures<a name="section1464106163817"></a>
**Table 1** Directory structure of the OpenHarmony driver framework
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="30.34%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="69.66%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row17666001869"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p4667601064"><a name="p4667601064"></a><a name="p4667601064"></a>hdf</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p154741318610"><a name="p154741318610"></a><a name="p154741318610"></a>Indicates the OpenHarmony driver framework.</p>
</td>
</tr>
<tr id="row17977171010144"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>hdf\frameworks</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>Provides the source code to develop the driver frameworks, driver models, and capability model libraries.</p>
</td>
</tr>
<tr id="row258624313915"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p858718432912"><a name="p858718432912"></a><a name="p858718432912"></a>hdf\frameworks\ability</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1866016071012"><a name="p1866016071012"></a><a name="p1866016071012"></a>Provides functional capabilities for the driver development, such as the message model libraries.</p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>hdf\frameworks\core</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>Provides the core code to implement the OpenHarmony driver framework.</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>hdf\frameworks\core\host</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p53051522133"><a name="p53051522133"></a><a name="p53051522133"></a>Provides functions of the driver host environment framework, including:</p>
<p id="p168291956191214"><a name="p168291956191214"></a><a name="p168291956191214"></a>1. Loading and starting a driver, and dispatching device nodes.</p>
<p id="p945834131310"><a name="p945834131310"></a><a name="p945834131310"></a>2. Dispatching events.</p>
<p id="p1365513245138"><a name="p1365513245138"></a><a name="p1365513245138"></a>3. Managing the internal power status.</p>
<p id="p113814121414"><a name="p113814121414"></a><a name="p113814121414"></a>4. Managing the common driver resource configurations.</p>
</td>
</tr>
<tr id="row138241821218"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p1138321861211"><a name="p1138321861211"></a><a name="p1138321861211"></a>hdf\frameworks\core\manager</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p103831518181211"><a name="p103831518181211"></a><a name="p103831518181211"></a>Provides the management modules of the driver framework, including:</p>
<p id="p1125114971315"><a name="p1125114971315"></a><a name="p1125114971315"></a>1. Driver API management module.</p>
<p id="p419655510136"><a name="p419655510136"></a><a name="p419655510136"></a>2. Driver configuration management module.</p>
<p id="p95776361144"><a name="p95776361144"></a><a name="p95776361144"></a>3. Device node management module.</p>
<p id="p75789456140"><a name="p75789456140"></a><a name="p75789456140"></a>4. Security management module.</p>
<p id="p183476761517"><a name="p183476761517"></a><a name="p183476761517"></a>5. Fault management module.</p>
</td>
</tr>
<tr id="row116251627171512"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p76251275152"><a name="p76251275152"></a><a name="p76251275152"></a>hdf\frameworks\core\shared</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p56256278150"><a name="p56256278150"></a><a name="p56256278150"></a>Provides shared code for the host and manager.</p>
</td>
</tr>
<tr id="row2306123015162"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p10306143019164"><a name="p10306143019164"></a><a name="p10306143019164"></a>hdf\frameworks\model</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1030713021612"><a name="p1030713021612"></a><a name="p1030713021612"></a>Provides a universal framework model for drivers.</p>
</td>
</tr>
<tr id="row2021312310176"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p421315312177"><a name="p421315312177"></a><a name="p421315312177"></a>hdf\frameworks\model\network</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p421313113179"><a name="p421313113179"></a><a name="p421313113179"></a>Provides network device models for drivers.</p>
</td>
</tr>
<tr id="row2167642189"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p21683416181"><a name="p21683416181"></a><a name="p21683416181"></a>hdf\frameworks\support\</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p71681548183"><a name="p71681548183"></a><a name="p71681548183"></a>Provides drivers with system APIs and hardware, such as GPIO, I2C, and SPI capabilities.</p>
<p id="p19848191416195"><a name="p19848191416195"></a><a name="p19848191416195"></a>Some interfaces can be migrated across platforms.</p>
</td>
</tr>
<tr id="row15342553171918"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p434255301916"><a name="p434255301916"></a><a name="p434255301916"></a>hdf\frameworks\support\osal</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1234211535198"><a name="p1234211535198"></a><a name="p1234211535198"></a>Provides platforms with common adaptation interfaces, such as memory, thread, and mutex.</p>
</td>
</tr>
<tr id="row116634294203"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p1866392919204"><a name="p1866392919204"></a><a name="p1866392919204"></a>hdf\frameworks\support\platform</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p5663329202017"><a name="p5663329202017"></a><a name="p5663329202017"></a>Provides APIs that support the common hardware of platforms, such as GPIO, I2C, and SPI capabilities.</p>
</td>
</tr>
<tr id="row193157275210"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p1331513279211"><a name="p1331513279211"></a><a name="p1331513279211"></a>hdf\frameworks\tools</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p131542762113"><a name="p131542762113"></a><a name="p131542762113"></a>Provides the driver capability libraries, such as the tool that configures and compiles the HCS (HDF Configuration Source).</p>
</td>
</tr>
<tr id="row66349163223"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p2634161611224"><a name="p2634161611224"></a><a name="p2634161611224"></a>hdf\frameworks\utils</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p26341516202215"><a name="p26341516202215"></a><a name="p26341516202215"></a>Provides basic data structures and algorithms.</p>
</td>
</tr>
<tr id="row1897841071415"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p16793185961315"><a name="p16793185961315"></a><a name="p16793185961315"></a>hdf\lite\adapter</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p14793959161317"><a name="p14793959161317"></a><a name="p14793959161317"></a>Adapts to kernel operation APIs and provides abstract APIs.</p>
</td>
</tr>
<tr id="row16448173512518"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p644893514514"><a name="p644893514514"></a><a name="p644893514514"></a>hdf\lite\include</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1744933517511"><a name="p1744933517511"></a><a name="p1744933517511"></a>Provides driver APIs for lightweight devices.</p>
</td>
</tr>
<tr id="row192731625216"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p10281116185217"><a name="p10281116185217"></a><a name="p10281116185217"></a>hdf\lite\hdi</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p7286165524"><a name="p7286165524"></a><a name="p7286165524"></a>Provides APIs of the OpenHarmony driver.</p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section1718733212019"></a>
None
## Use<a name="section8496817141616"></a>
**Figure 2** Interaction between the driver and framework<a name="fig1254113325118"></a>
![](figures/en-us_image_0000001052764349.png)
Driver loading is mostly done by the driver framework, and you only need to register and configure required APIs. The driver framework will load and initialize the driver based on the parsing result.
Driver development based on the HDF consists of the following three parts:
1. Driver: develop the functions.
2. Information configuration: present the loading information of the driver.
3. Resource configuration: configure the hardware information of the driver.
The driver mainly aims to develop the functions.
The first part that catches your eyes is the driver entry, which is described through **DriverEntry** alignment.
Three APIs are available, namely **bind**, **init**, and **release**.
```
struct HdfDriverEntry g_deviceSample = {
.moduleVersion = 1,
.moduleName = "sample_driver",
.Bind = SampleDriverBind,
.Init = SampleDriverInit,
.Release = SampleDriverRelease,
};
```
**Bind**: This API is used to bind driver devices and its functions.
```
int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject)
{
// TODO: Bind device service to device object.
// And you can also initialize device resources here.
return HDF_SUCCESS;
}
```
**Init**: When devices are successfully bound, the framework calls **Init** to initialize the driver. After initialization is complete, the driver framework will determine whether to create external service APIs based on the configuration file.
If the driver fails to be initialized, the driver framework will automatically release the created device API.
```
int32_t SampleDriverInit(struct HdfDeviceObject *deviceObject)
{
// TODO: Init hardware or other resources here.
return HDF_SUCCESS;
}
```
**Release**: When you need to uninstall a driver, the drive framework calls this function to release the driver resources. Then, other internal resources will be released.
```
void SampleDriverRelease(struct HdfDeviceObject *deviceObject)
{
// Release all resources.
return;
}
```
## Installation<a name="section14778154275818"></a>
The OpenHarmony driver is mainly deployed in the kernel space using the static link mode. It is compiled and packed with the kernel subsystem and system image.
**Figure 3** OpenHarmony driver installation<a name="fig675692712"></a>
![](figures/en-us_image_0000001053044331.png)
## Repositories Involved<a name="section134812226297"></a>
drivers\_hdf\_frameworks
drivers\_hdf\_lite
# Globalization Subsystem<a name="EN-US_TOPIC_0000001054438981"></a>
## Overview<a name="section11516137123416"></a>
Users can set the locale regarding about 68 languages and regions on OpenHarmony devices. As the locale settings are synchronized from one OpenHarmony device to another during interconnection, multi-language resource backtracking and multi-language preference support should be taken into account.
The global resource manager mainly provides the following capabilities:
- Multi-language resource backtracking: Users in different regions have their own cultural background and use their respective native languages. During resource loading, it is critical to support multi-language locale settings, specifically, to use as few languages as possible to match users' particular cultural background.
- Multi-language preference support: One of users' multiple preferred languages is selected and displayed for users \(for example, the Swiss\) who have multiple native languages.
## Repositories Involved<a name="section5889165803317"></a>
global\_frameworks\_resmgr\_lite
global\_interfaces\_innerkits\_resmgr\_lite
# Graphics Subsystem<a name="EN-US_TOPIC_0000001051979319"></a>
## Overview<a name="section5243712115918"></a>
The graphics subsystem mainly includes user interface \(UI\) components, layout, animator, font, input event, window management, rendering and drawing modules. It builds an application framework based on the LiteOS to develop applications on Internet of Things \(IoT\) devices with small hardware resources.
Module description:
- Components: provides application components, including the UIView, UIViewGoup, UIButton, UILabel, UILabelButton, UIList, and UISlider.
- Layout: lays out components, including Flexlayout, GridLayout, and ListLayout.
- Animator: defines functions for customizing animators.
- Fonts: defines functions related to fonts.
- Event: processes basic events, including click, press, drag, and long press.
- Tasks: manages tasks.
- Input: processes input events.
- Display: processes display events.
- Render: renders and draws components.
- Draw2d: draws lines, rectangles, circles, arcs, images, and texts, and interconnects with software rendering and hardware acceleration.
- Surface: applies for and releases shared memory.
- Window: manages windows, including creating, showing, hiding a window, and combining windows.
- Adapter: interconnects with underlying interfaces of the adaptation layer.
## Directory Structure<a name="section99241319175914"></a>
**Table 1** Directory structure of source code for the graphics subsystem
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="17.7%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="82.3%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>config</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>Configuration files</p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>frameworks/surface</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>Shared memory</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>frameworks/ui</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p0793185971316"><a name="p0793185971316"></a><a name="p0793185971316"></a>UI module, which defines functions related to UI components, animators and fonts.</p>
</td>
</tr>
<tr id="row1897841071415"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p16793185961315"><a name="p16793185961315"></a><a name="p16793185961315"></a>hals</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p14793959161317"><a name="p14793959161317"></a><a name="p14793959161317"></a>Hardware abstraction layer (HAL) logic</p>
</td>
</tr>
<tr id="row1420633124613"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p16207133194613"><a name="p16207133194613"></a><a name="p16207133194613"></a>interfaces/ui</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p182076317465"><a name="p182076317465"></a><a name="p182076317465"></a>Header files of open APIs related to the UI module</p>
</td>
</tr>
<tr id="row1679114715461"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p1079120477466"><a name="p1079120477466"></a><a name="p1079120477466"></a>interfaces/utils</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p1279144754611"><a name="p1279144754611"></a><a name="p1279144754611"></a>Header files of utils for the graphics subsystem</p>
</td>
</tr>
<tr id="row1534591617478"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p43456161472"><a name="p43456161472"></a><a name="p43456161472"></a>services/ims</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p23451616124717"><a name="p23451616124717"></a><a name="p23451616124717"></a>Input event management, including processing and distributing input events such as click and press.</p>
</td>
</tr>
<tr id="row1044522874716"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p644516283476"><a name="p644516283476"></a><a name="p644516283476"></a>services/wms</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p194451528144716"><a name="p194451528144716"></a><a name="p194451528144716"></a>Window management, including creating, managing, and combining windows.</p>
</td>
</tr>
<tr id="row48471930154713"><td class="cellrowborder" valign="top" width="17.7%" headers="mcps1.2.3.1.1 "><p id="p4847830134713"><a name="p4847830134713"></a><a name="p4847830134713"></a>utils</p>
</td>
<td class="cellrowborder" valign="top" width="82.3%" headers="mcps1.2.3.1.2 "><p id="p8847193074715"><a name="p8847193074715"></a><a name="p8847193074715"></a>Public library of the graphics subsystem</p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section37625514114"></a>
- Language version
- C++ 11 or later
- The specifications of the application framework vary depending on the System-on-a-Chip \(SoC\) and underlying OS capabilities.
- Cortex-M RAM and ROM:
- RAM: greater than 100 KB \(recommended\)
- ROM: greater than 300 KB
- Cortex-A RAM/ROM:
- RAM: greater than 1 MB \(recommended\)
- ROM: greater than 1 MB
## Adding a UI Component<a name="section266451716115"></a>
All components inherit from the base class UIView and share common attributes and styles. UI components are classified into common and container ones. You can add child components for a container component, but not for a common component.
Store new header files in the **interfaces/ui/components** directory and .cpp files in the **frameworks/ui/src/components** directory. Override **OnDraw** function to draw this UI component. Add the new file to the **frameworks/ui/BUILD.gn** directory and it will be compiled to **libui.so** during building.
## Repositories Involved<a name="section78781240113620"></a>
graphic\_lite
# JS Application Framework<a name="EN-US_TOPIC_0000001052342972"></a>
## Introduction<a name="section11660541593"></a>
The JS application framework allows you to develop web-like applications across platforms. The framework uses Toolkit to pack your **.hml**, **.css**, and **.js** files to a JavaScript bundle, parses the bundle, and renders it with view components of the C++ native UI. You can use the declarative APIs to develop applications. This allows data to drive view changes and avoids a large number of view operations, greatly simplifying application development.
The following figure shows the framework modules.
![](figures/js-framework.png)
## Directory Structure<a name="section1464106163817"></a>
The source code of the framework is stored in **/foundation/ace**. The following shows the directory structure.
```
/foundation/ace
├── frameworks #Framework code
│ └── lite
│ ├── examples #Sample code
│ ├── include #Exposed header files
│ ├── packages #JavaScript implementation
│ ├── src #Source code
│ ├── targets #Configuration file of each target device
│ └── tools #Tool code
├── interfaces #APIs exposed externally
│ └── innerkits #Header files of internal subsystems
│ └── builtin #JavaScript third-party module APIs exposed by the JS application framework
```
## Constraints<a name="section1718733212019"></a>
- Language version
- C++11 or later
- JavaScript ES5.1 or later
- Framework runtime memory consists of:
- Pre-allocated memory for running the JavaScript engine. The memory size is adjustable and depends on the complexity of the device application. Generally, 64 KB to 512 KB is recommended.
- Memory for the framework itself. For devices whose memory capacity exceeds 100 KB, the framework memory can be managed by a pre-allocated memory pool, which can be shared with the native UI framework. The memory pool manages objects and heap memory in a unified manner.
- The framework provides different specifications for various chip platforms and underlying OS capabilities.
- Cortex-M RAM and ROM
- JavaScript engine memory pool: greater than 48 KB \(recommended\)
- RAM: memory pool shared with the native UI \(recommended\). The size must be greater than 80 KB.
- ROM: greater than 300 KB \(for the JS application framework and related subsystems, such as native UI and JavaScript engine\)
- Cortex-A RAM and ROM
- JavaScript engine memory pool: greater than 128 KB \(recommended\)
- RAM: greater than 512 KB \(recommended\)
- ROM: greater than 2 MB \(for the JS application framework and related subsystems, such as native UI and JavaScript engine\)
## Using targets<a name="section1460013282612"></a>
The implementation of the JS application framework consists of two parts: native and JavaScript. The native part is developed by C++ and is the main body of the framework. The JavaScript part supports the runtime environment of JavaScript files, and supports the interaction between the JavaScript runtime and native framework through some global functions or objects exposed to the JavaScript engine.
The framework uses feature macros to customize function code to be compiled on different platforms. The feature macros are stored in header files in **foundation/ace/frameworks/lite/targets**. The directory structure is as follows:
```
/foundation/ace/frameworks/lite/targets
├── default/
│ └── acelite_config.h
├── linux/ #Linux environment configuration files
│ └── acelite_config.h
├── liteos_a/ #Environment configuration files for LiteOS Cortex-A
│ └── acelite_config.h
├── liteos_m/ #Environment configuration files for LiteOS Cortex-M
│ └── acelite_config.h
├── platform_adapter.cpp
├── platform_adapter.h
└── simulator/ #Simulator environment configuration files
└── win/
└── acelite_config.h*
```
When compiling for different platform targets, use the **acelite\_config.h** file in the corresponding platform directory. You can configure the header file searching path for compilation to locate the file to use. The following takes **ninja** and **cmake** build tools as examples:
ninja:
```
if (hos_kernel_type == "liteos_a" || hos_kernel_type == "liteos_m" ||
hos_kernel_type == "liteos_riscv") {// Select different header file searching paths based on the target kernel platform.
include_dirs += [ "targets/liteos-a" ]
} else if (hos_kernel_type == "linux") {
include_dirs += [ "targets/linux" ]
}
```
cmake:
```
......
set(ACE_LITE_CONFIG_PATH "${CMAKE_CURRENT_SOURCE_DIR}/targets/simulator/win")
set(JSFWK_INCLUDE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/include")
set(JSFWK_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/src/core")
set(UIKIT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ui")
set(THIRTY_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../third_party")
set(JSFWK_SIMULATOR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../tools/simulator")
set(JS_API_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../api/emui_band/MoltenCore/application/framework/ace/api")
set(JSFWK_SIMULATOR_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../tools/simulator")
set(AAFWK_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../../../aafwk")
# header files
include_directories(
${ACE_LITE_CONFIG_PATH}
${JSFWK_INCLUDE_PATH}/async
${JSFWK_INCLUDE_PATH}/base
${JSFWK_INCLUDE_PATH}/context
${JSFWK_INCLUDE_PATH}/jsi
${JSFWK_SOURCE_PATH}
......
```
The **acelite\_config.h** file is used to enable or disable the feature macros of different platforms. It can also be used to define constants for shielding platform differences. For example, platform file systems are different, and the names of some fixed directories might be different. These constants can be defined as follows:
**liteos-a/acelite\_config.h**
```
#define JS_FRAMEWORK_PATH "//system/ace/bin/"
```
**simulator/win/acelite\_config.h**
```
#define JS_FRAMEWORK_PATH "..\\..\\..\\jsfwk\\packages\\runtime-core\\build"
```
## Using Runtime-core<a name="section1460223932718"></a>
Runtime-core is a JavaScript-based simple data hijacking framework provided by the JS application framework to implement unidirectional data binding. The directory structure is as follows:
```
/foundation/ace/frameworks/lite/packages
└── runtime-core
├── .babelrc #Babel configuration file
├── .editorconfig #IDE configuration file
├── .eslintignore #Configuration file of the ESLint tool. You can set a directory or files that will not be scanned by the ESLint tool.
├── .eslintrc.js #ESLint configuration file for scanning rules.
├── .gitignore
├── package.json #NPM file
├── package-lock.json #NPM dependency lock file
├── .prettierrc #Configuration file for code formatting rules
├── scripts #Directory for compilation scripts
│ ├── build.js #Compilation script
│ └── configs.js #Rollup configuration file
├── .size-snapshot.json
└── src #Source code
├── core #ViewModel core implementation code
│ └── index.js
├── index.js
├── observer #Data hijacking implementation code
│ ├── index.js
│ ├── observer.js
│ ├── subject.js
│ └── utils.js
├── profiler #profiler directory
│ └── index.js
└── __test__ #Test cases
└── index.test.js
```
The following NPM commands are supported:
- **npm run build**
The JavaScript engine integrated in the JS application framework supports ES5.1 syntax only. However, the runtime-core is implemented using JavaScript ES6. Therefore, you should use Babel for ES6 code degradation and use Rollup to package the code. Run the **npm run build** command, and the packaged files are output to the **build** directory.
```
build/
├── framework-dev.js // Framework code used by the development environment (uncompressed and obfuscated)
├── framework-dev.min.js // Framework code used in the development environment (compressed and obfuscated)
├── framework-dev.js // Framework code used by the production environment (uncompressed and obfuscated)
├── framework-dev.min.js // Framework code used in the production environment (compressed and obfuscated)
```
- **npm run test**
Runtime-core uses Jest for unit testing. Run the **npm run test** command to start the unit test.
## Repositories Involved<a name="section11703194974217"></a>
ace\_lite\_jsfwk
ace\_interfaces\_innerkits\_builtin
# Kernel Subsystem<a name="EN-US_TOPIC_0000001051340509"></a>
## Overview<a name="section12995104752113"></a>
The OpenHarmony kernel is a real-time OS kernel developed by Huawei for IoT devices. It is as lightweight as RTOS and as easy-to-use as Linux.
The kernel repository is used to store the source code of the OpenHarmony kernel components, including process and thread scheduling, memory management, IPC mechanism, and timer management, as well as the version package compilation information.
## Directory Structure<a name="section1121775732114"></a>
**Table 1** Directory structure of the OpenHarmony lightweight kernel source code
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="30.34%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="69.66%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p2793159171311"><a name="p2793159171311"></a><a name="p2793159171311"></a>apps</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>User-space init and shell application program</p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p37931659101311"><a name="p37931659101311"></a><a name="p37931659101311"></a>arch</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>System architecture, such as ARM</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p117935599130"><a name="p117935599130"></a><a name="p117935599130"></a>bsd</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p0793185971316"><a name="p0793185971316"></a><a name="p0793185971316"></a>Code of the driver and adaptation layer module related to the FreeBSD, such as the USB module</p>
</td>
</tr>
<tr id="row113263612392"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p2133163611390"><a name="p2133163611390"></a><a name="p2133163611390"></a>compat</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1913313364399"><a name="p1913313364399"></a><a name="p1913313364399"></a>Compatibility with the kernel POSIX interfaces</p>
</td>
</tr>
<tr id="row15700172218399"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p10701622113920"><a name="p10701622113920"></a><a name="p10701622113920"></a>fs</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p270110222398"><a name="p270110222398"></a><a name="p270110222398"></a>File system module, which mainly derives from the NuttX open-source project</p>
</td>
</tr>
<tr id="row1897841071415"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p16793185961315"><a name="p16793185961315"></a><a name="p16793185961315"></a>kernel</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p14793959161317"><a name="p14793959161317"></a><a name="p14793959161317"></a>Kernel modules including the process, memory, and IPC modules</p>
</td>
</tr>
<tr id="row172848480398"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p728414485392"><a name="p728414485392"></a><a name="p728414485392"></a>lib</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p12284154818399"><a name="p12284154818399"></a><a name="p12284154818399"></a>Kernel library</p>
</td>
</tr>
<tr id="row5827141194012"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p48272110403"><a name="p48272110403"></a><a name="p48272110403"></a>net</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p28272119406"><a name="p28272119406"></a><a name="p28272119406"></a>Network module, which mainly derives from the lwip open-source project</p>
</td>
</tr>
<tr id="row980916239407"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p080910232403"><a name="p080910232403"></a><a name="p080910232403"></a>platform</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p11809202324018"><a name="p11809202324018"></a><a name="p11809202324018"></a>Code for supporting different systems on a chip (SOCs), such as Hi3516DV300</p>
</td>
</tr>
<tr id="row194244440402"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p0424124412401"><a name="p0424124412401"></a><a name="p0424124412401"></a>security</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p442410448409"><a name="p442410448409"></a><a name="p442410448409"></a>Code related to security features, including process permission management and virtual ID mapping management</p>
</td>
</tr>
<tr id="row674312515406"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p1274395114012"><a name="p1274395114012"></a><a name="p1274395114012"></a>syscall</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p1374365134011"><a name="p1374365134011"></a><a name="p1374365134011"></a>System calls</p>
</td>
</tr>
<tr id="row6470183019419"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p17470143094117"><a name="p17470143094117"></a><a name="p17470143094117"></a>test</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p547013018415"><a name="p547013018415"></a><a name="p547013018415"></a>Kernel and user-space test cases</p>
</td>
</tr>
<tr id="row343553564120"><td class="cellrowborder" valign="top" width="30.34%" headers="mcps1.2.3.1.1 "><p id="p54351735114113"><a name="p54351735114113"></a><a name="p54351735114113"></a>tools</p>
</td>
<td class="cellrowborder" valign="top" width="69.66%" headers="mcps1.2.3.1.2 "><p id="p17435635114116"><a name="p17435635114116"></a><a name="p17435635114116"></a>Code related to compilation configuration and <strong id="b1181842313414"><a name="b1181842313414"></a><a name="b1181842313414"></a>menuconfig</strong></p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section1967115154223"></a>
By default, the JFFS2 file system is used during system startup. This file system is read-write. If other file systems need to be used, the configurations of the file systems must be added accordingly.
## Usage<a name="section1821123352217"></a>
For details, see [en-us\_bookmap\_0000001050030794.md\#en-us\_topic\_0000001050032743](en-us_bookmap_0000001050030794.md#en-us_topic_0000001050032743).
## Repositories Involved<a name="section2392425183215"></a>
drivers\_liteos
kernel\_liteos\_a
kernel\_liteos\_a\_huawei\_proprietary\_fs\_proc
kernel\_liteos\_m
# Media Subsystem<a name="EN-US_TOPIC_0000001051344264"></a>
## Overview<a name="section38510214395"></a>
This repository stores source code information of the multimedia subsystem. It provides unified interfaces for you to develop media applications. With this repository, you can easily obtain media resources and focus on service development.
Based on code information about this repository, the device configuration file is stored in **test\\lite\\devini**. When using the configuration file, you can place it in the **/data** directory of the development board in use. You use the configuration file for the adaption to the sensor, resolution, frame rate, and more.
Subsystem architecture
![](figures/en-us_image_0000001055193837.png)
Service process
![](figures/en-us_image_0000001055193731.png)
As shown in these figures, the multimedia subsystem consists of camera, recorder, and player modules. The camera module provides YUV or RGB, JPEG, and H.264 or H.265 data, which is stored in the surface \(shared memory\); the recorder module packs H.264 or H.265 and AAC data in the surface into MP4 files; the player module demultiplexes the MP4 files into audio and video data, sends the data to corresponding decoders, and then plays the audio and video.
## Directory Structure<a name="section1937963913399"></a>
**Table 1** Directory structure of multimedia source code \(native APIs\)
<a name="table2977131081412"></a>
<table><thead align="left"><tr id="row7977610131417"><th class="cellrowborder" valign="top" width="40.71%" id="mcps1.2.3.1.1"><p id="p18792459121314"><a name="p18792459121314"></a><a name="p18792459121314"></a>Directory</p>
</th>
<th class="cellrowborder" valign="top" width="59.29%" id="mcps1.2.3.1.2"><p id="p77921459191317"><a name="p77921459191317"></a><a name="p77921459191317"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row17977171010144"><td class="cellrowborder" valign="top" width="40.71%" headers="mcps1.2.3.1.1 "><p id="p13476517134113"><a name="p13476517134113"></a><a name="p13476517134113"></a>foundation\multimedia\frameworks</p>
</td>
<td class="cellrowborder" valign="top" width="59.29%" headers="mcps1.2.3.1.2 "><p id="p879375920132"><a name="p879375920132"></a><a name="p879375920132"></a>Internal framework implementation, including <strong id="b1696433143010"><a name="b1696433143010"></a><a name="b1696433143010"></a>Audio</strong>, <strong id="b19075193012"><a name="b19075193012"></a><a name="b19075193012"></a>Camera</strong>, and <strong id="b19889207193019"><a name="b19889207193019"></a><a name="b19889207193019"></a>Player.Recorder</strong></p>
</td>
</tr>
<tr id="row6978161091412"><td class="cellrowborder" valign="top" width="40.71%" headers="mcps1.2.3.1.1 "><p id="p167373014417"><a name="p167373014417"></a><a name="p167373014417"></a>foundation\multimedia\interfaces\kits</p>
</td>
<td class="cellrowborder" valign="top" width="59.29%" headers="mcps1.2.3.1.2 "><p id="p6793059171318"><a name="p6793059171318"></a><a name="p6793059171318"></a>External header files</p>
</td>
</tr>
<tr id="row6978201031415"><td class="cellrowborder" valign="top" width="40.71%" headers="mcps1.2.3.1.1 "><p id="p1639221134214"><a name="p1639221134214"></a><a name="p1639221134214"></a>foundation\multimedia\services\media_lite</p>
</td>
<td class="cellrowborder" valign="top" width="59.29%" headers="mcps1.2.3.1.2 "><p id="p182076317465"><a name="p182076317465"></a><a name="p182076317465"></a>Underlying service implementation</p>
</td>
</tr>
<tr id="row1420633124613"><td class="cellrowborder" valign="top" width="40.71%" headers="mcps1.2.3.1.1 "><p id="p1569213233619"><a name="p1569213233619"></a><a name="p1569213233619"></a>foundation\multimedia\utils\lite</p>
</td>
<td class="cellrowborder" valign="top" width="59.29%" headers="mcps1.2.3.1.2 "><p id="p069215273618"><a name="p069215273618"></a><a name="p069215273618"></a>Common module implementation</p>
</td>
</tr>
<tr id="row1679114715461"><td class="cellrowborder" valign="top" width="40.71%" headers="mcps1.2.3.1.1 "><p id="p0295211184214"><a name="p0295211184214"></a><a name="p0295211184214"></a>foundation\multimedia\test\lite</p>
</td>
<td class="cellrowborder" valign="top" width="59.29%" headers="mcps1.2.3.1.2 "><p id="p1279144754611"><a name="p1279144754611"></a><a name="p1279144754611"></a>API testing code</p>
</td>
</tr>
</tbody>
</table>
## Constraints<a name="section722512541395"></a>
- C++11 or later
- Currently, Hi3516DV300 and Hi3518EV300 are supported, and only Hi3516DV300 supports the playback function.
## Installation<a name="section11914418405"></a>
- Load the kernel and related drivers before installing the repository. For details, see readme files of kernel and driver subsystems.
- Modify required configuration files, such as those in **test/devini**. For details, see the _Configuration File Description_. Currently, only IMX335 and IMX327 sensors are supported. For other sensors, seek help from the open source community.
- For details about how to invoke native APIs, see the demonstration in the **test** directory.
## Use Case<a name="section1467220266400"></a>
You can use media APIs to record, preview, and play audios and videos. Before using these resources, create a **CameraKit** object and register various callbacks to respond to many events in the media module. You create a **Camera** object to operate camera resources, for example, to start preview, recording, and stream capturing, and set related parameters.
The following example overrides the event class:
```
/*
* Copyright (c) 2020 Huawei Device 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 "camera_kit.h"
#include "recorder.h"
#include <sys/time.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
using namespace std;
using namespace OHOS;
using namespace OHOS::Media;
static void SampleSaveCapture(const char *p, uint32_t size)
{
cout << "Start saving picture" << endl;
struct timeval tv;
gettimeofday(&tv, NULL);
struct tm *ltm = localtime(&tv.tv_sec);
if (ltm != nullptr) {
ostringstream ss("Capture_");
ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg";
ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc);
cout << "write " << size << " bytes" << endl;
pic.write(p, size);
cout << "Saving picture end" << endl;
}
}
Recorder *SampleCreateRecorder()
{
int ret = 0;
int32_t sampleRate = 48000;
int32_t channelCount = 1;
AudioCodecFormat audioFormat = AAC_LC;
AudioSourceType inputSource = AUDIO_MIC;
int32_t audioEncodingBitRate = sampleRate;
VideoSourceType source = VIDEO_SOURCE_SURFACE_ES;
int32_t frameRate = 30;
float fps = 30;
int32_t rate = 4096;
int32_t sourceId = 0;
int32_t audioSourceId = 0;
int32_t width = 1920;
int32_t height = 1080;
VideoCodecFormat encoder;
encoder = HEVC;
width = 1920;
height = 1080;
Recorder *recorder = new Recorder();
if ((ret = recorder->SetVideoSource(source, sourceId)) != SUCCESS) {
cout << "SetVideoSource failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetVideoEncoder(sourceId, encoder)) != SUCCESS) {
cout << "SetVideoEncoder failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetVideoSize(sourceId, width, height)) != SUCCESS) {
cout << "SetVideoSize failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetVideoFrameRate(sourceId, frameRate)) != SUCCESS) {
cout << "SetVideoFrameRate failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetVideoEncodingBitRate(sourceId, rate)) != SUCCESS) {
cout << "SetVideoEncodingBitRate failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetCaptureRate(sourceId, frameRate)) != SUCCESS) {
cout << "SetCaptureRate failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetAudioSource(inputSource, audioSourceId)) != SUCCESS) {
cout << "SetAudioSource failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetAudioEncoder(audioSourceId, audioFormat)) != SUCCESS) {
cout << "SetAudioEncoder failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetAudioSampleRate(audioSourceId, sampleRate)) != SUCCESS) {
cout << "SetAudioSampleRate failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetAudioChannels(audioSourceId, channelCount)) != SUCCESS) {
cout << "SetAudioChannels failed." << ret << endl;
delete recorder;
return nullptr;
}
if ((ret = recorder->SetAudioEncodingBitRate(audioSourceId, audioEncodingBitRate)) != SUCCESS) {
cout << "SetAudioEncodingBitRate failed." << ret << endl;
delete recorder;
return nullptr;
}
return recorder;
}
class SampleFrameStateCallback : public FrameStateCallback {
void OnFrameFinished(Camera &camera, FrameConfig &fc, FrameResult &result) override
{
cout << "Receive frame complete inform." << endl;
if (fc.GetFrameConfigType() == FRAME_CONFIG_CAPTURE) {
cout << "Capture frame received." << endl;
list<Surface *> surfaceList = fc.GetSurfaces();
for (Surface *surface : surfaceList) {
SurfaceBuffer *buffer = surface->AcquireBuffer();
if (buffer != nullptr) {
char *virtAddr = static_cast<char *>(buffer->GetVirAddr());
if (virtAddr != nullptr) {
SampleSaveCapture(virtAddr, buffer->GetSize());
}
surface->ReleaseBuffer(buffer);
}
delete surface;
}
delete &fc;
}
}
};
class SampleCameraStateMng : public CameraStateCallback {
public:
SampleCameraStateMng() = delete;
SampleCameraStateMng(EventHandler &eventHdlr) : eventHdlr_(eventHdlr) {}
~SampleCameraStateMng()
{
if (recorder_ != nullptr) {
recorder_->Release();
delete recorder_;
}
}
void OnCreated(Camera &c) override
{
cout << "Sample recv OnCreate camera." << endl;
auto config = CameraConfig::CreateCameraConfig();
config->SetFrameStateCallback(&fsCb_, &eventHdlr_);
c.Configure(*config);
cam_ = &c;
}
void OnCreateFailed(const std::string cameraId, int32_t errorCode) override {}
void OnReleased(Camera &c) override {}
void StartRecord()
{
int ret;
if (isRecording_) {
cout << "Camera is already recording." << endl;
return;
}
if (recorder_ == nullptr) {
recorder_ = SampleCreateRecorder();
}
if (recorder_ == nullptr) {
cout << "Recorder not available" << endl;
return;
}
string path = "/sdcard";
ret = recorder_->SetOutputPath(path);
if (ret != SUCCESS) {
cout << "SetOutputPath fialed :" << ret << std::endl;
return;
}
ret = recorder_->Prepare();
if (ret != SUCCESS) {
cout << "Prepare failed.=" << ret << endl;
return;
}
Surface *surface = (recorder_->GetSurface(0)).get();
surface->SetWidthAndHeight(1920, 1080);
surface->SetQueueSize(3);
surface->SetSize(1024 * 1024);
FrameConfig *fc = new FrameConfig(FRAME_CONFIG_RECORD);
fc->AddSurface(*surface);
ret = recorder_->Start();
if (ret != SUCCESS) {
delete fc;
cout << "recorder start failed. ret=" << ret << endl;
return;
}
ret = cam_->TriggerLoopingCapture(*fc);
if (ret != 0) {
delete fc;
cout << "camera start recording failed. ret=" << ret << endl;
return;
}
isRecording_ = true;
cout << "camera start recording succeed." << endl;
}
void StartPreview()
{
if (isPreviewing_) {
cout << "Camera is already previewing." << endl;
return;
}
FrameConfig *fc = new FrameConfig(FRAME_CONFIG_PREVIEW);
Surface *surface = Surface::CreateSurface();
if (surface == nullptr) {
delete fc;
cout << "CreateSurface failed" << endl;
return;
}
surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */
surface->SetUserData("region_position_x", "0");
surface->SetUserData("region_position_y", "0");
surface->SetUserData("region_width", "480");
surface->SetUserData("region_height", "480");
fc->AddSurface(*surface);
int32_t ret = cam_->TriggerLoopingCapture(*fc);
if (ret != 0) {
delete fc;
cout << "camera start preview failed. ret=" << ret << endl;
return;
}
delete surface;
isPreviewing_ = true;
cout << "camera start preview succeed." << endl;
}
void Capture()
{
if (cam_ == nullptr) {
cout << "Camera is not ready." << endl;
return;
}
FrameConfig *fc = new FrameConfig(FRAME_CONFIG_CAPTURE);
Surface *surface = Surface::CreateSurface();
if (surface == nullptr) {
delete fc;
cout << "CreateSurface failed" << endl;
return;
}
surface->SetWidthAndHeight(1920, 1080); /* 1920:width,1080:height */
fc->AddSurface(*surface);
cam_->TriggerSingleCapture(*fc);
}
void Stop()
{
if (cam_ == nullptr) {
cout << "Camera is not ready." << endl;
return;
}
if (recorder_ != nullptr) {
recorder_->Stop(false);
}
cam_->StopLoopingCapture();
isPreviewing_ = false;
isRecording_ = false;
}
private:
bool isPreviewing_ = false;
bool isRecording_ = false;
EventHandler &eventHdlr_;
Camera *cam_ = nullptr;
Recorder *recorder_ = nullptr;
SampleFrameStateCallback fsCb_;
};
class SampleCameraDeviceCallback : public CameraDeviceCallback {};
void SampleHelp()
{
cout << "*******************************************" << endl;
cout << "Select the behavior of avrecorder." << endl;
cout << "1: Capture" << endl;
cout << "2: Record(Press s or S to stop)" << endl;
cout << "3: Preview(Press s or S to stop)" << endl;
cout << "q: quit the sample." << endl;
cout << "*******************************************" << endl;
}
int main()
{
cout << "Camera sample begin." << endl;
SampleHelp();
CameraKit *camKit = CameraKit::GetInstance();
if (camKit == nullptr) {
cout << "Can not get CameraKit instance" << endl;
return 0;
}
list<string> camList = camKit->GetCameraIds();
string camId;
for (auto &cam : camList) {
cout << "camera name:" << cam << endl;
const CameraAbility *ability = camKit->GetCameraAbility(cam);
/* Find the camera that fits your ability. */
list<CameraPicSize> sizeList = ability->GetSupportedSizes(0);
if (find(sizeList.begin(), sizeList.end(), CAM_PIC_1080P) != sizeList.end()) {
camId = cam;
break;
}
}
if (camId.empty()) {
cout << "No available camera.(1080p wanted)" << endl;
return 0;
}
EventHandler eventHdlr; // Create a thread to handle callback events
SampleCameraStateMng CamStateMng(eventHdlr);
camKit->CreateCamera(camId, CamStateMng, eventHdlr);
char input;
while (cin >> input) {
switch (input) {
case '1':
CamStateMng.Capture();
break;
case '2':
CamStateMng.StartRecord();
break;
case '3':
CamStateMng.StartPreview();
break;
case 's':
CamStateMng.Stop();
break;
case 'q':
CamStateMng.Stop();
goto EXIT;
default:
SampleHelp();
break;
}
}
EXIT:
cout << "Camera sample end." << endl;
return 0;
}
```
## Repositories Involved<a name="section7666411192217"></a>
multimedia\_frameworks\_camera\_lite
multimedia\_frameworks\_audio\_lite
multimedia\_frameworks\_player\_lite
multimedia\_frameworks\_recorder\_lite
multimedia\_hals\_camera\_lite
multimedia\_interfaces\_kits\_recorder\_lite
multimedia\_interfaces\_kits\_audio\_lite
multimedia\_interfaces\_kits\_camera\_lite
multimedia\_interfaces\_kits\_player\_lite
multimedia\_services\_media\_lite
multimedia\_utils\_lite
# Overview<a name="EN-US_TOPIC_0000001054438981"></a>
## Globalization Subsystem<a name="section11516137123416"></a>
Users can set the locale regarding about 68 languages and regions on OpenHarmony devices. As the locale settings are synchronized from one OpenHarmony device to another during interconnection, multi-language resource backtracking and multi-language preference support should be taken into account.
The global resource manager mainly provides the following capabilities:
- Multi-language resource backtracking: Users in different regions have their own cultural background and use their respective native languages. During resource loading, it is critical to support multi-language locale settings, specifically, to use as few languages as possible to match users' particular cultural background.
- Multi-language preference support: One of users' multiple preferred languages is selected and displayed for users \(for example, the Swiss\) who have multiple native languages.
## Repositories Involved<a name="section5889165803317"></a>
global\_frameworks\_resmgr\_lite
global\_interfaces\_innerkits\_resmgr\_lite
# Security Subsystem<a name="EN-US_TOPIC_0000001051982984"></a>
## Overview<a name="section6309125817418"></a>
This section provides samples about how to use existing security mechanisms to improve system security features, including secure boot, application permission management, inter-process communication \(IPC\) authentication, Huawei Universal Keystore Service \(HUKS\), HiChain, and application signature verification.
## Directory Structure<a name="section5614117756"></a>
**Directory 1**
```
security
├── framework
│ ├── appverify Application signature verification
│ ├── crypto_lite Encryption and decryption
│ ├── hichainsdk_lite Device authentication
│ ├── huks_lite Key and certificate management
│ ├── secure_os Secure OS
├── interface Interface directory
│ ├── innerkits Internal kit directory
│ │ ├── appverify Application signature verification
│ │ ├── crypto_lite Encryption and decryption
│ │ ├── hichainsdk_lite Device authentication
│ │ ├── huks_lite Key and certificate management
│ │ ├── iam_lite Application permission management
│ │ ├── secure_os Secure OS
│ ├── kits External kit directory
│ │ ├── iam_lite Application permission management
├── services Implementation
│ ├── iam_lite Application permission management
│ ├── secure_os Secure OS
```
**Directory 2**
```
kernel/liteos-a/security/
├── cap Capability mechanism
│ ├── BUILD.gn
│ ├── capability_api.h
│ ├── capability.c
│ ├── capability_type.h
│ └── Makefile
```
## Constraints<a name="section14134111467"></a>
C programming language is used. The preceding security features are mainly used on Cortex-A or devices with equivalent processing capabilities. On Cortex-M or devices with equivalent processing capabilities, only HUKS and HiChain are available.
## Secure Boot<a name="section10750510104718"></a>
To generate a x509 image package, perform compilation to generate the required binary images, including kernel images **kernel.bin** \(liteos/OHOS\_Image\) and **rootfs.img**. If the Hi3516DV300 chip is used, the generated images are stored in the **out\\ipcamera\_hi3516dv300\_liteos\_a** directory. Copy the binary images and the secure uboot private keys \(in the **vendor\\hisi\\hi35xx\\hi3516dv300\\uboot\\secureboot\_release** directory\) to the **secureboot\_ohos** directory \(in the **vendor\\hisi\\hi35xx\\hi3516dv300\\uboot** directory\). Go to the **x509\_creater** directory, run the **./creater.sh** command, and generate the x509 certificate as prompted. Return to the **secureboot\_ohos** directory and run **./sec\_os.sh** to generate the x509 image package.
## Application Permission Management<a name="section20822104317111"></a>
Application permissions are used to control access to system resources and features. These include personal privacy-related features or data in some scenarios, for example, hardware features of personal devices such as cameras and microphones, and personal data such as contacts and calendar data. OpenHarmony protects such data and features through application permission management.
To declare the permissions required by an application, edit **req-permissions** in the **HarmonyProfile.json** file in the installation bundle. The following figure shows an example.
**Figure 1** Declaring permissions<a name="fig1168867141611"></a>
![](figures/declaring-permissions.png "declaring-permissions")
Field descriptions
<a name="table1073153511418"></a>
<table><thead align="left"><tr id="row11107193541417"><th class="cellrowborder" valign="top" width="22.220000000000002%" id="mcps1.1.4.1.1"><p id="p6107535141420"><a name="p6107535141420"></a><a name="p6107535141420"></a>Field</p>
</th>
<th class="cellrowborder" valign="top" width="35.099999999999994%" id="mcps1.1.4.1.2"><p id="p111080352143"><a name="p111080352143"></a><a name="p111080352143"></a>Value</p>
</th>
<th class="cellrowborder" valign="top" width="42.68%" id="mcps1.1.4.1.3"><p id="p161080358141"><a name="p161080358141"></a><a name="p161080358141"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row151081735111418"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.1.4.1.1 "><p id="p1108193521417"><a name="p1108193521417"></a><a name="p1108193521417"></a>name</p>
</td>
<td class="cellrowborder" valign="top" width="35.099999999999994%" headers="mcps1.1.4.1.2 "><p id="p131081435151413"><a name="p131081435151413"></a><a name="p131081435151413"></a>String</p>
</td>
<td class="cellrowborder" valign="top" width="42.68%" headers="mcps1.1.4.1.3 "><p id="p0108235141411"><a name="p0108235141411"></a><a name="p0108235141411"></a>Permission name</p>
</td>
</tr>
<tr id="row19108143516148"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.1.4.1.1 "><p id="p51081355145"><a name="p51081355145"></a><a name="p51081355145"></a>reason</p>
</td>
<td class="cellrowborder" valign="top" width="35.099999999999994%" headers="mcps1.1.4.1.2 "><p id="p01082358147"><a name="p01082358147"></a><a name="p01082358147"></a>Multi-language string ID</p>
</td>
<td class="cellrowborder" valign="top" width="42.68%" headers="mcps1.1.4.1.3 "><p id="p191081235171414"><a name="p191081235171414"></a><a name="p191081235171414"></a>Purpose of requesting the permission.</p>
<p id="p3108193571412"><a name="p3108193571412"></a><a name="p3108193571412"></a>The purposes include reviewing requests for publishing applications, pop-up authorization, and permission management by users.</p>
</td>
</tr>
<tr id="row13108123516145"><td class="cellrowborder" valign="top" width="22.220000000000002%" headers="mcps1.1.4.1.1 "><p id="p18109835101415"><a name="p18109835101415"></a><a name="p18109835101415"></a>used-scene{</p>
<p id="p910913358146"><a name="p910913358146"></a><a name="p910913358146"></a>ability,</p>
<p id="p11109235181420"><a name="p11109235181420"></a><a name="p11109235181420"></a>when</p>
<p id="p16109193531417"><a name="p16109193531417"></a><a name="p16109193531417"></a>}</p>
</td>
<td class="cellrowborder" valign="top" width="35.099999999999994%" headers="mcps1.1.4.1.2 "><p id="p4109123511420"><a name="p4109123511420"></a><a name="p4109123511420"></a><strong id="b1164855864917"><a name="b1164855864917"></a><a name="b1164855864917"></a>ability</strong>: string of the component class name</p>
<p id="p19109133531410"><a name="p19109133531410"></a><a name="p19109133531410"></a><strong id="b12827212500"><a name="b12827212500"></a><a name="b12827212500"></a>when</strong>: <strong id="b4362946506"><a name="b4362946506"></a><a name="b4362946506"></a>inuse</strong> and <strong id="b182868713508"><a name="b182868713508"></a><a name="b182868713508"></a>always</strong></p>
</td>
<td class="cellrowborder" valign="top" width="42.68%" headers="mcps1.1.4.1.3 "><p id="p31091835151413"><a name="p31091835151413"></a><a name="p31091835151413"></a>Scene where the APIs controlled by this permission are called.</p>
<p id="p910943517141"><a name="p910943517141"></a><a name="p910943517141"></a>This field declares the components that call the APIs controlled by this permission and whether the APIs are called from the foreground or from both the foreground and background.</p>
</td>
</tr>
</tbody>
</table>
## IPC Authentication<a name="section156859591110"></a>
- If system services registered with Samgr provide APIs for other processes to access the services through IPC, access control policies must be configured; otherwise, access to the system services will be denied.
- You can configure access control policies in **base/security/services/iam\_lite/include/policy\_preset.h**. You need to configure the policy for each feature and then add the policies of features to the global policy.
For example, to configure an access policy for the BMS service, whose service registered with Samgr is **bundlems** and whose registered feature is **BmsFeature**, perform the following operations:
1. Define the feature policy. You can configure multiple features and configure multiple access policies for each feature.
**Figure 2** Example feature policy<a name="fig715515221920"></a>
![](figures/example-feature-policy.png "example-feature-policy")
There are three types of access policies:
**Figure 3** Access policy structure<a name="fig1848524515915"></a>
![](figures/access-policy-structure.png "access-policy-structure")
- **RANGE**: Processes with a UID within a specified range are allowed to access **BmsFeature**. **uidMin** and **uidMax** need to be specified.
- **FIXED**: Processes with specified UIDs are allowed to access **BmsFeature**. **fixedUid** needs to be specified. A maximum number of eight UIDs can be configured.
- **BUNDLENAME**: Only a specified application is allowed to access **BmsFeature**. **bundleName** needs to be specified.
2. Add the defined feature policy to the global policy. You need to configure the number of features.
**Figure 4** Registering a feature policy<a name="fig1181753551014"></a>
![](figures/registering-a-feature-policy.png "registering-a-feature-policy")
UID allocation rules:
Init/foundation process: 0
appspawn process: 1
Shell process: 2
kitfw process: 3
Other built-in services: 4–99
System applications \(such as settings\): 100–999
Preset applications \(such as Wallet and Taobao\): 1000–9999
Common third-party applications: 10000 to **INT\_MAX**
## HUKS<a name="section9819115764715"></a>
In distributed scenarios, trust relationships need to be established between devices with varied hardware capabilities and system environments. A typical application is HiChain for trusted interconnection between devices. In this case, a unified key management service is required to ensure consistent APIs and key data formats, and provide industry-standard encryption/decryption algorithms. HUKS is such a service that provides unified key management and encryption/decryption.
HUKS consists of native APIs, the hardware abstraction layer \(HAL\), and Core Module.
1. Native APIs are implemented using the C language to ensure consistency among all devices, and include the APIs for key generation, encryption, and decryption.
2. Core Module depends on the HAL and provides core functions such as encryption and decryption, signature verification, and key storage.
3. HAL shields differences between hardware and OSs and defines the unified APIs for HUKS. It contains platform algoIOrithm libraries, file systems, and logs.
## HiChain<a name="section19390142934814"></a>
**Device Interconnection Security**
To transmit user data securely between devices, ensure that the devices are trusted by each other. A trust relationship and a secure data transmission channel must be established between the devices. This section describes how an IoT controller and IoT device establish a trust relationship.
![](figures/en-us_image_0000001052584330.png)
- **IoT device interconnection security**
A trust relationship can be established between an IoT device that runs OpenHarmony \(such as the AI speaker, smart home device, and wearable device\) and an IoT controller \(such as the smartphone and tablet\). Encrypted user data can be transmitted between the IoT device and IoT controller through a secure connection.
- **IoT service identifier of the IoT controller**
An IoT controller generates different identifiers for different IoT device management services to isolate these services. The identifier can be used for authentication and communication between an IoT controller and an IoT device. It is an Ed25519 public/private key pair generated using the elliptic curve cryptography.
- **IoT device identifier**
An IoT device can generate its own device identifier for communicating with the IoT controller. It is also an Ed25519 public/private key pair generated using elliptic curve cryptography, with the private key stored on the IoT device. Each time the device is restored to factory settings, the public/private key pair will be reset.
The identifier can be used for secure communication between the IoT controller and IoT device. After the devices exchange the service identifier or device identifier, they can negotiate the key and establish a secure communication channel.
- **P2P trusted binding between devices**
When an IoT controller and an IOT device establish a trust relationship, they exchange identifiers.
During this process, the user needs to enter or scan the PIN provided by the IoT device on the IoT controller. PIN is either dynamically generated if the IoT device has a screen, or preset by the manufacturer if it does not have a screen. A PIN can be a number or a QR code. Then the IoT controller and IoT device perform authentication and session key exchange based on password authenticated key exchange \(PAKE\), and use the session key to encrypt the channel for exchanging identity public keys.
**Secure communication between the IoT controller and IoT device**
When an IoT controller and an IoT device communicate with each other after establishing a trust relationship, they authenticate each other by using the locally stored identity public key of the peer. Bidirectional identity authentication and session key exchange are performed using the Station-to-Station \(STS\) protocol during each communication. The session key is used to encrypt the data transmission channel between the devices.
## Application Signature Verification<a name="section15468226154919"></a>
To ensure the integrity of application content, HarmonyOS uses application signatures and profiles to manage application sources. Only pre-installed applications and applications from HUAWEI AppGallery can be installed on devices.
**Basic Concepts**
- **Developer certificate**
Identity digital certificate of a developer, which is used to sign local debugging software
- **Application debugging profile**
Application debugging authorization file that allows you to install and debug an application on a specified device
- **Application publishing certificate**
Identity digital certificate of an application publisher, which is used to sign an application to be published or preset
- **Application publishing profile**
Description file of an application, which is used for reviewing an application to be published or preset
- **APPID**
Unique identifier of an application, which consists of the application bundle name and the public key of the application publishing certificate
**How Application Signature Verification Works**
1. Apply for becoming an authorized application developer on HUAWEI AppGallery.
2. Install and debug an application on a specified device.
3. Publish the application.
## **Signature of an Application Published on HUAWEI AppGallery**<a name="section1273895216490"></a>
- **Application debugging scenario**
To develop and debug applications for HarmonyOS devices, you need to apply for becoming an authorized application developer on HUAWEI AppGallery. You need to generate a public/private key pair and upload the public key to HUAWEI AppGallery. HUAWEI AppGallery creates a developer certificate based on your identity information and the uploaded public key, and issues the certificate through the developer certificate CA. You also need to upload the application information and debugging device ID for creating an application debugging profile, which contains the HUAWEI AppGallery signature and cannot be tampered with. Upon obtaining the developer certificate and application debugging profile, you can install and debug applications signed with the private key on a specified HarmonyOS device.
The application installation service of HarmonyOS verifies the application signature to ensure application integrity. In addition, the service verifies the developer certificate, application debugging profile, and the mapping between them to ensure the validity of your identity and the application.
![](figures/en-us_image_0000001051282241.png)
- **Application publishing**
To publish applications in HUAWEI AppGallery, you need to use the application publishing certificate and profile issued by HUAWEI AppGallery to sign the applications. As shown in the following figure, the procedure of applying for the application publishing certificate and profile is similar to that of applying for the developer certificate and application debugging profile \(you can use the same public/private key pair\). Applications signed by the application publishing certificate cannot be directly installed on devices. Instead, the applications must be published in HUAWEI AppGallery for review. After the applications are reviewed and approved, HUAWEI AppGallery uses the publishing certificate to re-sign the applications. The re-signed applications can be downloaded and installed by users.
The application installation service of HarmonyOS verifies the application signature to ensure application integrity. In addition, the service checks whether the signature certificate is from HUAWEI AppGallery to ensure that the application is trusted.
![](figures/en-us_image_0000001051562162.png)
## Repositories Involved<a name="section1665013282177"></a>
security\_services\_app\_verify
security\_frameworks\_crypto\_lite
security\_services\_hichainsdk\_lite
security\_services\_huks\_lite
security\_frameworks\_secure\_os
security\_interfaces\_innerkits\_hichainsdk\_lite
security\_interfaces\_innerkits\_iam\_lite
security\_interfaces\_innerkits\_huks\_lite
security\_interfaces\_innerkits\_app\_verify
security\_interfaces\_innerkits\_crypto\_lite
security\_interfaces\_innerkits\_secure\_os
security\_interfaces\_kits\_iam\_lite
security\_services\_iam\_lite
security\_services\_secure\_os
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
......@@ -134,18 +134,18 @@ When collecting personal data, clearly and explicitly notify users of the data t
Adhering to the preceding principles, we have designed some examples for your reference. The figure below shows an example of a privacy notice or statement.
**Figure 1** Example of a dialog box showing a privacy notice or statement<a name="en-us_topic_0000001051770800_fig19449113175619"></a>
**Figure 1** Example of a dialog box showing a privacy notice or statement<a name="en-us_topic_0000001051770800_fig1546516294210"></a>
![](figures/example-of-a-dialog-box-showing-a-privacy-notice-or-statement.png "example-of-a-dialog-box-showing-a-privacy-notice-or-statement")
- Personal data shall be collected for specified, explicit, and legitimate purposes and not further processed in a manner that is incompatible with those purposes. If the purposes are changed or an individual withdraws the consent, you shall obtain user consent again before using the data. The figures below show examples of a privacy statement change and content withdrawal, respectively.
**Figure 2** Example of a dialog box showing a privacy notice or statement change<a name="en-us_topic_0000001051770800_fig1788416493354"></a>
![](figures/example-of-a-dialog-box-showing-a-privacy-notice-or-statement-change.png "example-of-a-dialog-box-showing-a-privacy-notice-or-statement-change")
**Figure 2** Example of a dialog box showing a privacy notice or statement<a name="en-us_topic_0000001051770800_fig3591610523"></a>
![](figures/example-of-a-dialog-box-showing-a-privacy-notice-or-statement-0.png "example-of-a-dialog-box-showing-a-privacy-notice-or-statement-0")
**Figure 3** Example of a dialog box showing consent withdrawal<a name="en-us_topic_0000001051770800_fig860521073616"></a>
**Figure 3** Example of a dialog box showing consent withdrawal<a name="en-us_topic_0000001051770800_fig12802152515583"></a>
![](figures/example-of-a-dialog-box-showing-consent-withdrawal.png "example-of-a-dialog-box-showing-consent-withdrawal")
![](figures/en-us_image_0000001054860198.png)
![](figures/隐私声明详情页面-弹窗02.png)
The download or upgrade of user system software or application software may involve the modification of users' private space. Users shall have the right to know and control such behavior. They shall be informed of such behavior and be given the option to agree or disagree with such behavior.
......
......@@ -274,7 +274,7 @@ None
ostringstream ss("Capture_");
ss << "Capture" << ltm->tm_hour << "-" << ltm->tm_min << "-" << ltm->tm_sec << ".jpg";
ofstream pic("/tmp/" + ss.str(), ofstream::out | ofstream::trunc);
ofstream pic("/sdcard/" + ss.str(), ofstream::out | ofstream::trunc);
cout << "write " << size << " bytes" << endl;
pic.write(p, size);
cout << "Saving picture end" << endl;
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册