提交 49def63f 编写于 作者: C chen 提交者: Gitee

Merge branch 'master' of gitee.com:openharmony/xts_acts into 725

...@@ -27,7 +27,7 @@ hcpptest_suite("ActsAbilityMgrTest") { ...@@ -27,7 +27,7 @@ hcpptest_suite("ActsAbilityMgrTest") {
"${appexecfwk_lite_path}/frameworks/bundle_lite:bundle", "${appexecfwk_lite_path}/frameworks/bundle_lite:bundle",
"//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared", "//base/hiviewdfx/hilog_lite/frameworks/featured:hilog_shared",
"//foundation/communication/ipc/interfaces/innerkits/c/ipc:ipc_single", "//foundation/communication/ipc/interfaces/innerkits/c/ipc:ipc_single",
"//foundation/distributeddatamgr/appdatamgr/kv_store/interfaces/inner_api/kv_store:kv_store", "//foundation/distributeddatamgr/kv_store/interfaces/inner_api/kv_store:kv_store",
"//foundation/systemabilitymgr/samgr_lite/samgr:samgr", "//foundation/systemabilitymgr/samgr_lite/samgr:samgr",
] ]
if (enable_ohos_appexecfwk_feature_ability == true) { if (enable_ohos_appexecfwk_feature_ability == true) {
......
...@@ -19,7 +19,7 @@ hctest_suite("ActsDbmKvStoreTest") { ...@@ -19,7 +19,7 @@ hctest_suite("ActsDbmKvStoreTest") {
include_dirs = [ include_dirs = [
"src", "src",
"//foundation/distributeddatamgr/appdatamgr/kv_store/interfaces/innerkits/dbm_kv_store/include", "//foundation/distributeddatamgr/kv_store/interfaces/innerkits/dbm_kv_store/include",
"//base/iot_hardware/peripheral/interfaces/kits", "//base/iot_hardware/peripheral/interfaces/kits",
] ]
cflags = [ "-Wno-error" ] cflags = [ "-Wno-error" ]
......
...@@ -19,11 +19,11 @@ hcpptest_suite("ActsKvStoreTest") { ...@@ -19,11 +19,11 @@ hcpptest_suite("ActsKvStoreTest") {
include_dirs = [ include_dirs = [
"src", "src",
"//foundation/distributeddatamgr/appdatamgr/kv_store/interfaces/inner_api/kv_store/include", "//foundation/distributeddatamgr/kv_store/interfaces/inner_api/kv_store/include",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
"//utils/native/lite/include", "//utils/native/lite/include",
] ]
deps = [ "//foundation/distributeddatamgr/appdatamgr/kv_store/interfaces/inner_api/kv_store:kv_store" ] deps = [ "//foundation/distributeddatamgr/kv_store/interfaces/inner_api/kv_store:kv_store" ]
cflags = [ "-Wno-error" ] cflags = [ "-Wno-error" ]
ldflags = [ ldflags = [
"-lstdc++", "-lstdc++",
......
...@@ -24,33 +24,6 @@ ...@@ -24,33 +24,6 @@
"moduleName": "entry", "moduleName": "entry",
"moduleType": "entry" "moduleType": "entry"
}, },
"defPermissions": [
{
"availableScope": [],
"grantMode": "system_grant",
"name": "publish_event0800_permission"
},
{
"availableScope": [],
"grantMode": "system_grant",
"name": "publish_event0900_subscriberPermissions"
},
{
"availableScope": [],
"grantMode": "system_grant",
"name": "publish_event0900_publisherPermission"
},
{
"availableScope": [],
"grantMode": "system_grant",
"name": "publish_event1000_permission"
},
{
"availableScope": [],
"grantMode": "system_grant",
"name": "permission.COMMONEVENT_STICKY"
}
],
"reqPermissions": [ "reqPermissions": [
{ {
"name": "publish_event0800_permission", "name": "publish_event0800_permission",
......
...@@ -19,70 +19,129 @@ var time = 1000 ...@@ -19,70 +19,129 @@ var time = 1000
var WantAgent; var WantAgent;
export default function ActsAnsWantAgentOneProTest() { export default function ActsAnsWantAgentOneProTest() {
describe('ActsAnsWantAgentOneProTest', function () { describe('ActsAnsWantAgentOneProTest', function () {
console.info('----ActsWantAgentTest----'); console.info("----ActsWantAgentTest----");
/* /*
* @tc.number: ACTS_SetWant_0200 * @tc.number: ACTS_SetWant_0200
* @tc.name: getWantAgent(OperationType.START_ABILITY) * @tc.name: getWantAgent(OperationType.START_ABILITY)
* @tc.desc: verify the function of getWantAgent(OperationType.START_ABILITY) * @tc.desc: verify the function of getWantAgent(OperationType.START_ABILITY)
*/ */
it('ACTS_SetWant_0200', 0, async function (done) { it("ACTS_SetWant_0200", 0, async function (done) {
var agentInfo = { var agentInfo = {
wants: [ wants: [
{ {
bundleName: "com.example.WantAgentTest1", bundleName: "com.example.WantAgentTest1",
abilityName: "com.example.WantAgentTest1.MainAbility", abilityName: "com.example.WantAgentTest1.MainAbility",
action: "action1", action: "action1",
entities: ["entity1"], entities: ["entity1"],
type: "MIMETYPE", type: "MIMETYPE",
uri: "key={true,true,false}", uri: "key={true,true,false}",
parameters: parameters: {
{ mykey0: 2222,
mykey0: 2222, mykey1: [1, 2, 3],
mykey1: [1, 2, 3], mykey2: "[1, 2, 3]",
mykey2: "[1, 2, 3]", mykey3: "ssssssssssssssssssssssssss",
mykey3: "ssssssssssssssssssssssssss", mykey4: [false, true, false],
mykey4: [false, true, false], mykey5: ["qqqqq", "wwwwww", "aaaaaaaaaaaaaaaaa"],
mykey5: ["qqqqq", "wwwwww", "aaaaaaaaaaaaaaaaa"], mykey6: true,
mykey6: true, },
} },
}, ],
], operationType: wantAgent.OperationType.START_ABILITY,
operationType: wantAgent.OperationType.START_ABILITY, requestCode: 0,
requestCode: 0, wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
wantAgentFlags:[wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG] };
console.info("----getWantAgent before----");
wantAgent.getWantAgent(agentInfo).then((data) => {
WantAgent = data;
console.info("----getWantAgent success!----");
console.info(JSON.stringify(data));
expect(typeof data).assertEqual("object");
var triggerInfo = {
code: 0,
};
wantAgent.trigger(WantAgent, triggerInfo, (err, data) => {
if (err.code == 0) {
console.info("----trigger success!----");
console.info("== trigger data " + JSON.stringify(data));
} else {
console.info("----trigger failed!----");
console.info("== trigger data " + JSON.stringify(data));
} }
console.info('----getWantAgent before----'); done();
wantAgent.getWantAgent(agentInfo).then( });
(data) => { done();
WantAgent = data; });
console.info('----getWantAgent success!----'); setTimeout(function () {
console.info(JSON.stringify(data)); console.debug("====>time out ACTS_SetWant_0200====>");
expect(typeof(data)).assertEqual("object"); }, time);
var triggerInfo = { console.info("----getWantAgent after----");
code:0 });
}
wantAgent.trigger(WantAgent, triggerInfo, /*
(err, data) => { * @tc.number: ACTS_SetWant_0300
if (err.code == 0) { * @tc.name: getWantAgent(OperationType.START_ABILITY)
console.info('----trigger success!----'); * @tc.desc: verify the function of getWantAgent(OperationType.START_ABILITY)
console.info('== trigger data ' + JSON.stringify(data) ); */
} else { it("ACTS_SetWant_0300", 0, async function (done) {
console.info('----trigger failed!----'); var agentInfo = {
console.info('== trigger data ' + JSON.stringify(data) ); wants: [
} {
done(); bundleName: "com.example.WantAgentTest1",
} abilityName: "com.example.WantAgentTest1.MainAbility",
); action: "action1",
done(); entities: ["entity1"],
type: "MIMETYPE",
} uri: "key={true,true,false}",
); parameters: {
setTimeout(function(){ mykey0: 2222,
console.debug("====>time out ACTS_SetWant_0200====>"); mykey1: [1, 2, 3],
}, time); mykey2: "[1, 2, 3]",
console.info('----getWantAgent after----'); mykey3: "ssssssssssssssssssssssssss",
}) mykey4: [false, true, false],
mykey5: ["qqqqq", "wwwwww", "aaaaaaaaaaaaaaaaa"],
mykey6: true,
},
},
],
operationType: wantAgent.OperationType.START_ABILITY,
requestCode: 0,
wantAgentFlags: [wantAgent.WantAgentFlags.UPDATE_PRESENT_FLAG],
extraInfo: {
key1:'test_extraInfo'
}
};
console.info("----getWantAgent before----");
wantAgent.getWantAgent(agentInfo).then((data) => {
WantAgent = data;
console.info("----getWantAgent success!----");
console.info(JSON.stringify(data));
expect(typeof data).assertEqual("object");
var triggerInfo = {
code: 0,
want:WantAgent,
permission:'',
extraInfo: {
key1:'test_triggerInfo'
}
};
wantAgent.trigger(WantAgent, triggerInfo, (err, data) => {
if (err.code == 0) {
console.info("----trigger success!----");
console.info("== trigger data " + JSON.stringify(data));
} else {
console.info("----trigger failed!----");
console.info("== trigger data " + JSON.stringify(data));
}
done();
});
done();
});
setTimeout(function () {
console.debug("====>time out ACTS_SetWant_0200====>");
}, time);
console.info("----getWantAgent after----");
});
}) })
} }
...@@ -334,6 +334,7 @@ describe("ActsSubscriberTestUnorder", async function (done) { ...@@ -334,6 +334,7 @@ describe("ActsSubscriberTestUnorder", async function (done) {
console.info("===============ActsSubscriberTestUnorder_0700==========================>"); console.info("===============ActsSubscriberTestUnorder_0700==========================>");
let commonEventSubscribeInfo = { let commonEventSubscribeInfo = {
events: ["publish_event0700"], events: ["publish_event0700"],
userId:100
}; };
let commonEventPublishData = { let commonEventPublishData = {
...@@ -357,6 +358,7 @@ describe("ActsSubscriberTestUnorder", async function (done) { ...@@ -357,6 +358,7 @@ describe("ActsSubscriberTestUnorder", async function (done) {
Subscriber.createSubscriber(commonEventSubscribeInfo).then((data) => { Subscriber.createSubscriber(commonEventSubscribeInfo).then((data) => {
console.info("===============ActsSubscriberTestUnorder_0700=========createSubscriber promise"); console.info("===============ActsSubscriberTestUnorder_0700=========createSubscriber promise");
expect(commonEventSubscribeInfo.userId).assertEqual(100)
commonEventSubscriber007 = data; commonEventSubscriber007 = data;
data.getSubscribeInfo().then(() => { data.getSubscribeInfo().then(() => {
console.info("===============ActsSubscriberTestUnorder_0700=========getSubscribeInfo promise"); console.info("===============ActsSubscriberTestUnorder_0700=========getSubscribeInfo promise");
......
...@@ -16,96 +16,140 @@ import emitter from '@ohos.events.emitter' ...@@ -16,96 +16,140 @@ import emitter from '@ohos.events.emitter'
import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium' import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from '@ohos/hypium'
export default function EmitterTest() { export default function EmitterTest() {
describe('EmitterTest', function () { describe('EmitterTest', function () {
console.info("===========EmitterTest start====================>"); console.info("===========EmitterTest start====================>");
var eventData = { var eventData = {
data: { data: {
"id": 1, "id": 1,
"content": "message", "content": "message",
}
} }
}
var InnerEventImmediate = { var InnerEventImmediate = {
eventId: 1, eventId: 1,
priority: emitter.EventPriority.IMMEDIATE priority: emitter.EventPriority.IMMEDIATE
} }
var InnerEventLow = { var InnerEventLow = {
eventId: 2, eventId: 2,
priority: emitter.EventPriority.LOW priority: emitter.EventPriority.LOW
} }
function callback(data){ function callback(data){
console.info('callback success'); console.info('callback success');
expect(data.eventId).assertEqual("message"); expect(data.eventId).assertEqual("message");
} }
function callback01(data){ function callback01(data){
console.info('callback success'); console.info('callback success');
expect(data.data.id).assertEqual(1); expect(data.data.id).assertEqual(1);
expect(data.data.content).assertEqual("message"); expect(data.data.content).assertEqual("message");
} }
/* /*
* @tc.number : EmitterOnTest * @tc.number : EmitterOnTest
* @tc.name : verify on : Check subscribe same on common ordered event * @tc.name : verify on : Check subscribe same on common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterOnTest" type of the interface (by Promise) * @tc.desc : Check the subscriber can receive event "EmitterOnTest" type of the interface (by Promise)
*/ */
it('EmitterOnTest', 0, async function (done) { it('EmitterOnTest', 0, async function (done) {
console.info("===========EmitterOnTest====================>"); console.info("===========EmitterOnTest====================>");
emitter.on(InnerEventImmediate, callback); emitter.on(InnerEventImmediate, callback);
done(); done();
}) })
/* /*
* @tc.number : EmitterOnceTest * @tc.number : EmitterOnceTest
* @tc.name : verify once : Check subscribe same once common ordered event * @tc.name : verify once : Check subscribe same once common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterOnceTest" type of the interface (by Promise) * @tc.desc : Check the subscriber can receive event "EmitterOnceTest" type of the interface (by Promise)
*/ */
it('EmitterOnceTest', 0, async function (done){ it('EmitterOnceTest', 0, async function (done){
console.info("===========EmitterOnceTest====================>"); console.info("===========EmitterOnceTest====================>");
emitter.once(InnerEventImmediate, callback); emitter.once(InnerEventImmediate, callback);
done(); done();
}) })
/* /*
* @tc.number : EmitterEmitTest * @tc.number : EmitterEmitTest
* @tc.name : verify emit : Check subscribe same emit common ordered event * @tc.name : verify emit : Check subscribe same emit common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterEmitTest" type of the interface (by Promise) * @tc.desc : Check the subscriber can receive event "EmitterEmitTest" type of the interface (by Promise)
*/ */
it('EmitterEmitTest', 0, async function (done){ it('EmitterEmitTest', 0, async function (done){
console.info("===========EmitterEmitTest====================>"); console.info("===========EmitterEmitTest====================>");
emitter.once(InnerEventImmediate, callback01); emitter.once(InnerEventImmediate, callback01);
emitter.emit(InnerEventImmediate, eventData); emitter.emit(InnerEventImmediate, eventData);
done(); done();
}) })
/* /*
* @tc.number : EmitterLowTest * @tc.number : EmitterLowTest
* @tc.name : verify low : Check subscribe same low common ordered event * @tc.name : verify low : Check subscribe same low common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterLowTest" type of the interface (by Promise) * @tc.desc : Check the subscriber can receive event "EmitterLowTest" type of the interface (by Promise)
*/ */
it('EmitterLowTest', 0, async function (done){ it('EmitterLowTest', 0, async function (done){
console.info("===========EmitterLowTest====================>"); console.info("===========EmitterLowTest====================>");
emitter.once(InnerEventLow, callback01); emitter.once(InnerEventLow, callback01);
emitter.emit(InnerEventLow,eventData); emitter.emit(InnerEventLow,eventData);
done(); done();
}) })
/*
* @tc.number : EmitterOffTest
* @tc.name : verify off : Check subscribe same off common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterOffTest" type of the interface (by Promise)
*/
it('EmitterOffTest', 0, async function (done){
console.info("===========EmitterOffTest111====================>");
emitter.once(InnerEventLow, callback01);
emitter.emit(InnerEventImmediate, eventData);
emitter.off(1);
done();
})
}) /*
* @tc.number : EmitterOffTest
* @tc.name : verify off : Check subscribe same off common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterOffTest" type of the interface (by Promise)
*/
it('EmitterOffTest', 0, async function (done){
console.info("===========EmitterOffTest111====================>");
emitter.once(InnerEventLow, callback01);
emitter.emit(InnerEventImmediate, eventData);
emitter.off(1);
done();
})
/*
* @tc.number : EmitterEmitTest_0100
* @tc.name : verify off : Check subscribe same off common ordered event
* @tc.desc : Check the subscriber can receive event "EmitterOffTest" type of the interface (by Promise)
*/
it('EmitterEmitTest_0100', 0, async function (done){
console.info("===========EmitterEmitTest_0100====================>");
var eventData2 = {
data: {
"content": "c",
"id": 2,
}};
var innerEventHigh = {
eventId: 3,
priority: emitter.EventPriority.HIGH
};
emitter.once(InnerEventLow, callback01);
emitter.emit(innerEventHigh, eventData2);
expect(emitter.EventPriority.HIGH).assertEqual(1)
done();
})
/*
* @tc.number : EmitterEmitTest_0200
* @tc.name : verify off : emitter.EventPriority.IDLE
* @tc.desc : emitter.EventPriority.IDLE
*/
it('EmitterEmitTest_0200', 0, async function (done){
console.info("===========EmitterEmitTest_0100====================>");
var eventData3 = {
data: {
"content": "d",
"id": 3,
}};
var innerEventIdle = {
eventId: 4,
priority: emitter.EventPriority.IDLE
};
emitter.once(innerEventIdle, callback01);
emitter.emit(InnerEventImmediate, eventData3);
expect(emitter.EventPriority.IDLE).assertEqual(3)
done();
})
})
} }
...@@ -28,7 +28,6 @@ _all_test_packages = [ ...@@ -28,7 +28,6 @@ _all_test_packages = [
"${ACTS_ROOT}/startup:startup", "${ACTS_ROOT}/startup:startup",
"${ACTS_ROOT}/sensors:sensor", "${ACTS_ROOT}/sensors:sensor",
"${ACTS_ROOT}/distributeddatamgr:distributeddatamgr", "${ACTS_ROOT}/distributeddatamgr:distributeddatamgr",
"${ACTS_ROOT}/updater:update",
"${ACTS_ROOT}/graphic:graphic", "${ACTS_ROOT}/graphic:graphic",
"${ACTS_ROOT}/arkui:arkui", "${ACTS_ROOT}/arkui:arkui",
"${ACTS_ROOT}/storage:storage", "${ACTS_ROOT}/storage:storage",
......
# Copyright (C) 2021 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.
import("//build/ohos_var.gni")
group("update") {
testonly = true
if (is_standard_system) {
deps = [ "update_test:update_js_test" ]
}
}
# Copyright (C) 2021 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.
import("//test/xts/tools/build/suite.gni")
ohos_js_hap_suite("update_js_test") {
hap_profile = "./src/main/config.json"
deps = [
":update_js_assets",
":update_js_resources",
]
certificate_profile = "./signature/openharmony_sx.p7b"
hap_name = "ActsUpdateJsTest"
}
ohos_js_assets("update_js_assets") {
source_dir = "./src/main/js/default"
}
ohos_resources("update_js_resources") {
sources = [ "./src/main/resources" ]
hap_profile = "./src/main/config.json"
}
{
"description": "Configuration for time js api Tests",
"driver": {
"type": "JSUnitTest",
"test-timeout": "180000",
"package": "ohos.acts.upgrade",
"shell-timeout": "60000"
},
"kits": [
{
"test-file-name": [
"ActsUpdateJsTest.hap"
],
"type": "AppInstallKit",
"cleanup-apps": true
}
]
}
{
"app": {
"bundleName": "ohos.acts.upgrade",
"vendor": "example",
"version": {
"code": 1,
"name": "1.0"
},
"apiVersion": {
"compatible": 4,
"target": 5
}
},
"deviceConfig": {},
"module": {
"package": "ohos.acts.upgrade",
"name": ".MyApplication",
"deviceType": [
"phone"
],
"distro": {
"deliveryWithInstall": true,
"moduleName": "entry",
"moduleType": "entry"
},
"abilities": [
{
"skills": [
{
"entities": [
"entity.system.home"
],
"actions": [
"action.system.home"
]
}
],
"name": "ohos.acts.upgrade.MainAbility",
"icon": "$media:icon",
"description": "$string:mainability_description",
"label": "$string:app_name",
"type": "page",
"launchType": "standard",
"visible": true
}
],
"js": [
{
"pages": [
"pages/index/index"
],
"name": "default",
"window": {
"designWidth": 720,
"autoDesignWidth": false
}
}
]
}
}
/*
* Copyright (C) 2021 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.
*/
export default {
onCreate() {
console.info('AceApplication onCreate');
},
onDestroy() {
console.info('AceApplication onDestroy');
}
};
{
"strings": {
"hello": "Hello",
"world": "World"
}
}
\ No newline at end of file
{
"strings": {
"hello": "您好",
"world": "世界"
}
}
\ No newline at end of file
.container {
flex-direction: column;
justify-content: center;
align-items: center;
}
.title {
font-size: 100px;
}
<div class="container">
<text class="title">
{{ $t('strings.hello') }} {{ title }}
</text>
</div>
/*
* Copyright (C) 2021 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.
*/
import {Core} from 'deccjsunit/lite'
const core = Core.getInstance()
core.init()
require('../../test/List.test.js')
core.execute()
export default {
data: {
title: ""
},
onInit() {
this.title = this.$t('strings.world');
}
}
/*
* Copyright (C) 2021 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.
*/
require('./update.test.js')
\ No newline at end of file
{
"string": [
{
"name": "app_name",
"value": "MyApplication0420"
},
{
"name": "mainability_description",
"value": "JS_Phone_Empty Feature Ability"
}
]
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册