diff --git a/OAT.xml b/OAT.xml
index df03b803c468eabd3b9ce50905bd9b77104b2940..c44c80974dafbb33b72de47ebba92f130c413368 100644
--- a/OAT.xml
+++ b/OAT.xml
@@ -67,6 +67,21 @@ Note:If the text contains special characters, please escape them according to th
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/common/include/dm_constants.h b/common/include/dm_constants.h
index c759db1587cb7544780d5a35e42653e0bf9a0357..18191989daaa2ab7f4761560838c4f3e1eff6592 100755
--- a/common/include/dm_constants.h
+++ b/common/include/dm_constants.h
@@ -153,6 +153,7 @@ constexpr const char* DM_CAPABILITY_CASTPLUS = "castPlus";
constexpr const char* DM_CAPABILITY_VIRTUAL_LINK = "virtualLink";
constexpr const char* DM_CAPABILITY_SHARE = "share";
constexpr const char* DM_CAPABILITY_WEAR = "wear";
+constexpr const char* DM_CAPABILITY_OOP = "oop";
constexpr const char* DM_CREDENTIAL_TYPE = "CREDENTIAL_TYPE";
constexpr const char* DM_CREDENTIAL_REQJSONSTR = "CREDENTIAL_REQJSONSTR";
constexpr const char* DM_CREDENTIAL_RETURNJSONSTR = "CREDENTIAL_RETURNJSONSTR";
@@ -264,6 +265,7 @@ constexpr const char* PARAM_CLOSE_SESSION_DELAY_SECONDS = "DM_CLOSE_SESSION_DELA
constexpr const char* DM_AUTHENTICATION_TYPE = "DM_AUTHENTICATION_TYPE";
constexpr const char* PARAM_KEY_CONN_SESSIONTYPE = "connSessionType";
+constexpr const char* PARAM_KEY_HML_RELEASETIME = "hmlReleaseTime";
constexpr const char* PARAM_KEY_HML_ENABLE_160M = "hmlEnable160M";
constexpr const char* PARAM_KEY_HML_ACTIONID = "hmlActionId";
@@ -298,6 +300,8 @@ constexpr int32_t MAX_ICON_SIZE = 4 * 1024 * 1024;
constexpr int32_t MAX_CONTAINER_SIZE = 500;
// One year 365 * 24 * 60 * 60
constexpr int32_t MAX_ALWAYS_ALLOW_SECONDS = 31536000;
+
+const std::string PICKER_PROXY_SPLIT = "_pickerProxy_";
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DM_CONSTANTS_H
\ No newline at end of file
diff --git a/common/src/dm_anonymous.cpp b/common/src/dm_anonymous.cpp
index 1ae4cd2b3d466c68f949c758166de3cdd1e36444..8241a39bf7f04123b7f0d8cca0df7712aa236b83 100644
--- a/common/src/dm_anonymous.cpp
+++ b/common/src/dm_anonymous.cpp
@@ -384,7 +384,7 @@ std::string GetSubStr(const std::string &rawStr, const std::string &separator, i
while (end != std::string::npos) {
strVec.push_back(rawStr.substr(start, end - start));
- start = end + 1;
+ start = end + separator.size();
end = rawStr.find(separator, start);
}
strVec.push_back(rawStr.substr(start));
diff --git a/common/src/ipc/standard/ipc_model_codec.cpp b/common/src/ipc/standard/ipc_model_codec.cpp
index a411577b387de86a79ddb46fff3c11caa7f80d38..527699df062e1e9e7dac3602dd3f89bd22dd70bb 100644
--- a/common/src/ipc/standard/ipc_model_codec.cpp
+++ b/common/src/ipc/standard/ipc_model_codec.cpp
@@ -51,6 +51,7 @@ void IpcModelCodec::DecodeDmDeviceBasicInfo(MessageParcel &parcel, DmDeviceBasic
LOGE("strcpy_s networkId failed!");
return;
}
+ devInfo.extraData = parcel.ReadString();
}
bool IpcModelCodec::EncodePeerTargetId(const PeerTargetId &targetId, MessageParcel &parcel)
diff --git a/display/@ohos.distributedDeviceManager.d.ts b/display/@ohos.distributedDeviceManager.d.ts
index 22accf7a6a1036bb1accc4b8e1cf4126695a3c7b..0aaaafef602eb89b4dade19633e0f18a3f7ccef6 100644
--- a/display/@ohos.distributedDeviceManager.d.ts
+++ b/display/@ohos.distributedDeviceManager.d.ts
@@ -54,7 +54,7 @@ declare namespace distributedDeviceManager {
* @syscap SystemCapability.DistributedHardware.DeviceManager
* @since 10
*/
- deviceType: number;
+ deviceType: string;
/**
* Device network id.
@@ -62,6 +62,14 @@ declare namespace distributedDeviceManager {
* @since 10
*/
networkId?: string;
+
+ /**
+ * Device extra data.
+ * @type { ?string }
+ * @syscap SystemCapability.DistributedHardware.DeviceManager
+ * @since 16
+ */
+ extraData?: string;
}
/**
diff --git a/display/AppScope/app.json b/display/AppScope/app.json
index b59a97e4df14784a98447e36a7a80b88e474bff6..c4e9d0b90f360e0ac8e0f84ffb8e901b65aaf702 100644
--- a/display/AppScope/app.json
+++ b/display/AppScope/app.json
@@ -2,8 +2,8 @@
"app": {
"bundleName": "com.ohos.devicemanagerui",
"vendor": "example",
- "versionCode": 1000034,
- "versionName": "1.0.34",
+ "versionCode": 1000035,
+ "versionName": "1.0.35",
"icon": "$media:app_icon",
"label": "$string:app_name",
"minAPIVersion": 10,
diff --git a/display/entry/src/main/ets/UIExtAbility/picker/DeviceSelectAbility.ets b/display/entry/src/main/ets/UIExtAbility/picker/DeviceSelectAbility.ets
new file mode 100644
index 0000000000000000000000000000000000000000..472482bb224854526fd065c477b1ae603f95e4d0
--- /dev/null
+++ b/display/entry/src/main/ets/UIExtAbility/picker/DeviceSelectAbility.ets
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2025 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 UIExtensionAbility from '@ohos.app.ability.UIExtensionAbility'
+import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession'
+import Want from '@ohos.app.ability.Want';
+const TAG = '[DeviceManagerUI:DeviceSelectAbility]==>';
+
+export default class DeviceSelectAbility extends UIExtensionAbility {
+ onSessionCreate(want: Want, session: UIExtensionContentSession) {
+ console.log(TAG, `UIExtAbility onSessionCreate`)
+ if (want.parameters != undefined) {
+ if (want.parameters.title) {
+ AppStorage.setOrCreate('title', want.parameters.title);
+ }
+ if (want.parameters.customDescription) {
+ AppStorage.setOrCreate('customDescription', want.parameters.customDescription);
+ }
+ if (want.parameters.operation) {
+ AppStorage.setOrCreate('operation', want.parameters.operation);
+ }
+ if (want.parameters.bundleName) {
+ AppStorage.setOrCreate('bundleName', want.parameters.bundleName);
+ }
+ if (want.parameters.moduleName) {
+ AppStorage.setOrCreate('moduleName', want.parameters.moduleName);
+ }
+ if (want.parameters.abilityName) {
+ AppStorage.setOrCreate('abilityName', want.parameters.abilityName);
+ }
+ let callerBundleName: string = want.parameters?.['ohos.aafwk.param.callerBundleName'] as string;
+ AppStorage.setOrCreate('callerBundleName', callerBundleName);
+ }
+ let param: Record = {
+ 'session': session
+ }
+ let storage: LocalStorage = new LocalStorage(param);
+ session.loadContent('pages/picker/DeviceSelect', storage);
+ session.setWindowBackgroundColor('#00000000');
+ let extensionHostWindow = session.getUIExtensionHostWindowProxy();
+ extensionHostWindow.hideNonSecureWindows(true);
+ session.setWindowPrivacyMode(true);
+ AppStorage.setOrCreate('deviceSelectSession', session);
+ }
+
+ onSessionDestroy(session: UIExtensionContentSession) {
+ let extensionHostWindow = session.getUIExtensionHostWindowProxy();
+ extensionHostWindow.hideNonSecureWindows(false);
+ console.log(TAG, `UIExtAbility onSessionDestroy`)
+ }
+}
\ No newline at end of file
diff --git a/display/entry/src/main/ets/pages/ConfirmDialog.ets b/display/entry/src/main/ets/pages/ConfirmDialog.ets
index ff783b9530dcf0f08eb9fd987cdc00cabbef205e..43a0bd10a0b8a510340fcc811da3c3057ed2523c 100644
--- a/display/entry/src/main/ets/pages/ConfirmDialog.ets
+++ b/display/entry/src/main/ets/pages/ConfirmDialog.ets
@@ -55,6 +55,7 @@ struct ConfirmCustomDialog {
this.peerDeviceName = AppStorage.get('deviceName') as string;
console.log('peerDeviceName is ' + this.peerDeviceName);
}
+ let customDescriptionStr: string = AppStorage.get('customDescriptionStr') as string;
let hostPkgLabel: string = AppStorage.get('hostPkgLabel') as string;
if (hostPkgLabel === CAST_PKG_NAME) {
this.title =
@@ -63,6 +64,9 @@ struct ConfirmCustomDialog {
this.title = context.resourceManager.getStringSync($r('app.string.dm_confirm_title_hap').id, hostPkgLabel,
this.peerDeviceName);
this.peerCustomDescription = context.resourceManager.getStringSync($r('app.string.dm_confirm_intention').id);
+ if (customDescriptionStr != undefined && customDescriptionStr != '') {
+ this.peerCustomDescription = this.peerDeviceName + customDescriptionStr;
+ }
} else {
let titleFirst: string =
context.resourceManager.getStringSync($r('app.string.dm_connect_device').id, this.peerDeviceName);
diff --git a/display/entry/src/main/ets/pages/picker/DeviceSelect.ets b/display/entry/src/main/ets/pages/picker/DeviceSelect.ets
new file mode 100644
index 0000000000000000000000000000000000000000..6b014010ed9f6daf84eff9e2051f333d7433bd9f
--- /dev/null
+++ b/display/entry/src/main/ets/pages/picker/DeviceSelect.ets
@@ -0,0 +1,590 @@
+/*
+ * Copyright (c) 2025 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 distributedDeviceManager from '@ohos.distributedDeviceManager';
+import { AsyncCallback, BusinessError, Callback, ErrorCallback } from '@ohos.base';
+import abilityAccessCtrl, { Context } from '@ohos.abilityAccessCtrl';
+import promptAction from '@ohos.promptAction';
+import UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
+import mediaquery from '@ohos.mediaquery';
+import deviceInfo from '@ohos.deviceInfo';
+import Constant from '../../common/constant';
+import accessibility from '@ohos.accessibility';
+import common from '@ohos.app.ability.common';
+let anmDuration: number = 800;
+let TAG = '[DeviceManagerUI:DeviceSelect]==>';
+
+enum StatusType {
+ Unbound = 0,
+ TrustBinding = 1,
+ Binding = 2
+}
+
+let customData: Record = {
+ 'operation': '',
+ 'object': '',
+ 'qResp': 1
+};
+
+let discoverParam: Record = {
+ 'discoverTargetType': 1,
+ 'CUSTOM_DATA': JSON.stringify(customData),
+ 'DISC_CAPABILITY': ''
+};
+let filterOptions: Record = {
+ 'availableStatus': 0
+};
+
+class Data {
+ public status?: StatusType = StatusType.Unbound
+ public device: distributedDeviceManager.DeviceBasicInfo = {
+ deviceId: '',
+ deviceName: '',
+ deviceType: '',
+ networkId: '',
+ extraData: '',
+ };
+}
+
+class DeviceStateData {
+ public action: distributedDeviceManager.DeviceStateChange = 0;
+ public device: distributedDeviceManager.DeviceBasicInfo = {
+ deviceId: '',
+ deviceName: '',
+ deviceType: '',
+ networkId: '',
+ extraData: '',
+ };
+}
+
+class Device {
+ public device: distributedDeviceManager.DeviceBasicInfo = {
+ deviceId: '',
+ deviceName: '',
+ deviceType: '',
+ networkId: '',
+ extraData: '',
+ }
+}
+
+class CustomData {
+ public operation: string = '';
+ public object: string = '';
+ public displayName: string = '';
+ public policyCode: number = 0;
+ public actionId: number = 0;
+}
+
+class ExtraData {
+ public CUSTOM_DATA: string = ''
+}
+
+class DeviceCallBack {
+ public deviceId: string = '';
+ public deviceName: string = '';
+ public bundlename: string = '';
+ public moudlename: string = '';
+ public ablityname: string = '';
+}
+
+class BindTargetData {
+ public deviceId: string = '';
+}
+
+@Entry
+@Component
+export struct Index {
+ @State showPhone: Visibility = Visibility.Visible;
+ @State showFlag: Visibility = Visibility.Visible;
+ @State deviceSelectSession : UIExtensionContentSession | undefined = undefined;
+ @State isAutoCancel: boolean = false;
+ @State deviceList: Data[] = [];
+ @State trustDeviceList: Data[] = [];
+ @State centerX: number = 0;
+ @State centerY: number = 0;
+ @State radius: number = 0;
+ @State deviceStateStatus: number = -1;
+ @State currentDevice: Data | undefined = undefined;
+ @State title: string | Resource = '';
+ @State operation: string = '';
+ @State customDescription: string | Resource = '';
+ @State bundleName: string = '';
+ @State moduleName: string = '';
+ @State abilityName: string = '';
+ @State isLandscape: boolean = true;
+ @State isListNum: number = 5;
+ @State discCapability: string = 'oop';
+ @State networIdMatchLen: number = -1;
+ listener = mediaquery.matchMediaSync('(orientation: landscape)');
+ dmInstance: distributedDeviceManager.DeviceManager | undefined = undefined;
+ context = getContext(this) as common.UIAbilityContext
+ bindParam: Record = {};
+ scroller: Scroller = new Scroller()
+
+ @Builder
+ CustomBuilder() {
+ Column() {
+ Stack() {
+ Image($r('app.media.iocn_phone_self')).width(54).draggable(false)
+ Image($r('app.media.phone')).width(30).draggable(false)
+ }
+ .width(54)
+ .height(54)
+ .borderRadius(54)
+ }
+ .width(68)
+ .height(92)
+ }
+
+ cancel() {
+ this.dmInstance!.stopDiscovering();
+ try {
+ console.log(TAG + 'terminateSelf');
+ this.deviceSelectSession = AppStorage.get('deviceSelectSession');
+ if (this.deviceSelectSession) {
+ this.deviceSelectSession.terminateSelf();
+ }
+ } catch (err) {
+ console.log(TAG + 'dialog cancel failed: ' + JSON.stringify(err));
+ }
+ }
+
+ deviceStateChange() {
+ try {
+ this.dmInstance!.on('deviceStateChange', (data: DeviceStateData) => {
+ if (data.action == 0 || data.action == 1) {
+ let deviceInfoList: distributedDeviceManager.DeviceBasicInfo[] =
+ this.dmInstance!.getAvailableDeviceListSync();
+ this.trustDeviceList = [];
+ deviceInfoList.forEach((item) => {
+ this.trustDeviceList.push({ device: item, status: StatusType.TrustBinding})
+ for (let i = 0; i < this.deviceList.length; i++) {
+ let deviceItem = this.deviceList[i]
+ if (this.isDeviceBasicEqual(deviceItem, item)) {
+ this.deviceList[i].status = StatusType.TrustBinding
+ this.deviceList.push(new Data())
+ this.deviceList.splice(this.deviceList.length - 1, 1)
+ }
+ }
+ })
+ let currentItem = this.currentDevice as Data
+ if (currentItem && this.isDeviceEqual(currentItem, data)) {
+ this.sendData(data.device.deviceId, data.device.networkId, data.device.deviceName)
+ }
+ }
+ if (data.action == 2) {
+ this.deviceList = this.deviceList.filter((item) => !this.isDeviceEqual(item, data))
+ }
+ });
+ } catch (err) {
+ let e: BusinessError = err as BusinessError;
+ console.error('deviceStateChange errCode:' + e.code + ',errMessage:' + e.message);
+ }
+ }
+
+ addProperty(data: Data) {
+ let extraDataStr: string = data.device.extraData == undefined ? '' : data.device.extraData
+ let extraData: ExtraData = JSON.parse(extraDataStr)
+ let customData: CustomData = JSON.parse(extraData.CUSTOM_DATA)
+ data.device.deviceName = customData.displayName
+ }
+
+ devListInfo() {
+ try {
+ this.deviceStateChange()
+ let deviceInfoList: distributedDeviceManager.DeviceBasicInfo[] =
+ this.dmInstance!.getAvailableDeviceListSync();
+ deviceInfoList.forEach((item) => {
+ this.trustDeviceList.push({ device: item, status: StatusType.TrustBinding })
+ })
+
+ customData = {
+ 'operation': this.operation,
+ 'object': this.bundleName,
+ 'qResp': 1
+ }
+ discoverParam = {
+ 'discoverTargetType': 1,
+ 'CUSTOM_DATA': JSON.stringify(customData),
+ 'DISC_CAPABILITY' : this.discCapability
+ }
+ this.dmInstance!.startDiscovering(discoverParam, filterOptions);
+ } catch (err) {
+ let e: BusinessError = err as BusinessError;
+ console.error('startDiscovering errCode:' + e.code + ',errMessage:' + e.message);
+ }
+ this.dmInstance!.on('discoverSuccess', (data: Data) => {
+ let arr: string[] = []
+ let result = this.deviceList.find((item: Data) => {
+ return this.isDeviceDataEqual(item, data)
+ })
+ if (!!result) {
+ return
+ }
+ this.deviceList.forEach((item) => {
+ arr.push(this.getMatchId(item.device.deviceId, item.device.networkId))
+ })
+ if (arr.indexOf(this.getMatchId(data.device.deviceId, data.device.networkId)) === -1) {
+ data.status = this.getStatusType(data)
+ this.deviceList.push(data)
+ }
+ });
+ }
+
+ getFullNetworkId(networkId: string | undefined): string {
+ let networkIdStr = networkId == undefined ? '' : networkId
+ let fullNetworkId = '';
+ this.trustDeviceList.forEach((item) => {
+ if (this.getMatchId('', item.device.networkId) == this.getMatchId('', networkIdStr)) {
+ fullNetworkId = item.device.networkId;
+ }
+ });
+ return fullNetworkId;
+ }
+
+ getStatusType(data: Data): StatusType {
+ let isTrust = false;
+ this.trustDeviceList.forEach((item) => {
+ if (this.isDeviceDataEqual(item, data)) {
+ isTrust = true
+ }
+ });
+ if (isTrust) {
+ return StatusType.TrustBinding
+ }
+ return StatusType.Unbound
+ }
+
+ getMatchId(deviceId: string, networkId: string | undefined): string {
+ networkId = networkId == undefined ? '' : networkId;
+ if (this.discCapability == 'oop') {
+ this.networIdMatchLen = 8;
+ if (networkId.length > this.networIdMatchLen) {
+ return networkId.substring(0, this.networIdMatchLen)
+ }
+ return networkId
+ }
+ return deviceId;
+ }
+
+ isDeviceEqual(device1: Data, device2: DeviceStateData): boolean {
+ return this.getMatchId(device1.device.deviceId, device1.device.networkId) ==
+ this.getMatchId(device2.device.deviceId, device2.device.networkId);
+ }
+
+ isDeviceBasicEqual(device1: Data, device2: distributedDeviceManager.DeviceBasicInfo): boolean {
+ return this.getMatchId(device1.device.deviceId, device1.device.networkId) ==
+ this.getMatchId(device2.deviceId, device2.networkId);
+ }
+
+ isDeviceDataEqual(device1: Data, device2: Data): boolean {
+ return this.getMatchId(device1.device.deviceId, device1.device.networkId) ==
+ this.getMatchId(device2.device.deviceId, device2.device.networkId);
+ }
+
+ initPickParms() {
+ if (AppStorage.get('title') != null) {
+ this.title = AppStorage.get('title') as string;
+ }
+ if (AppStorage.get('customDescription') != null) {
+ this.customDescription = AppStorage.get('customDescription') as string;
+ }
+ if (AppStorage.get('operation') != null) {
+ this.operation = AppStorage.get('operation') as string;
+ }
+ if (AppStorage.get('bundleName') != null) {
+ this.bundleName = AppStorage.get('callerBundleName') as string;
+ }
+ if (AppStorage.get('moduleName') != null) {
+ this.moduleName = AppStorage.get('moduleName') as string;
+ }
+ if (AppStorage.get('abilityName') != null) {
+ this.abilityName = AppStorage.get('abilityName') as string;
+ }
+ let bundleName = `com.ohos.devicemanagerui_pickerProxy_${this.bundleName}`
+ this.dmInstance = distributedDeviceManager.createDeviceManager(bundleName);
+ }
+
+ calcPositionX(index: number): number {
+ let angle = -160 + (index * 160 / this.isListNum)
+ let radian = angle * Math.PI / 180
+ return this.centerX + Math.cos(radian) * this.radius
+ }
+
+ calcPositionY(index: number): number {
+ let angle = -160 + (index * 160 / this.isListNum)
+ let radian = angle * Math.PI / 180
+ return this.centerY + Math.sin(radian) * this.radius
+ }
+
+ sendData(deviceId: string, networkId: string | undefined, deviceName: string) {
+ this.deviceSelectSession = AppStorage.get('deviceSelectSession');
+ let callBack: DeviceCallBack = {
+ deviceId: deviceId,
+ deviceName: deviceName,
+ bundlename: this.bundleName,
+ moudlename: this.moduleName,
+ ablityname: this.abilityName,
+ }
+ let fullNetworkId = this.getFullNetworkId(networkId)
+ console.info('sendData:' + JSON.stringify(callBack));
+ this.deviceSelectSession.sendData({'deviceId' : deviceId, 'networkId' : fullNetworkId, 'deviceName' : deviceName})
+ this.cancel()
+ }
+
+ bindTarget(item: Data, index: number) {
+ this.currentDevice = item
+ if (item.status == 0) {
+ try {
+ this.bindParam = {
+ 'bindType': 1,
+ 'targetPkgName': 'xxxx',
+ 'appName': 'xxxx',
+ 'appOperation': 'xxxx',
+ 'customDescription': this.customDescription,
+ 'bundleName': this.bundleName,
+ 'context': this.context
+ };
+ this.dmInstance!.bindTarget(item.device.deviceId, this.bindParam,
+ (err: BusinessError, data: BindTargetData) => {
+ if (err) {
+ console.error('======bindTarget errCode:' + err.code + ',errMessage:' + err.message);
+ return;
+ }
+ });
+ } catch (err) {
+ let e: BusinessError = err as BusinessError;
+ console.error('bindTarget errCode:' + e.code + ',errMessage:' + e.message);
+ }
+ } else {
+ try {
+ this.dmInstance!.unbindTarget(item.device.deviceId);
+ this.deviceList[index].status = StatusType.Unbound
+ this.deviceList.push(new Data())
+ this.deviceList.splice(this.deviceList.length - 1, 1)
+ } catch (err) {
+ let e: BusinessError = err as BusinessError;
+ console.error('unbindTarget errCode:' + e.code + ',errMessage:' + e.message);
+ }
+ }
+ }
+
+ onPortrait(mediaQueryResult: mediaquery.MediaQueryResult) {
+ console.info('mediaQueryResult.matches:' + mediaQueryResult.matches)
+ if (mediaQueryResult.matches) {
+ this.isLandscape = true
+ this.isListNum = 8
+ } else {
+ this.isLandscape = false
+ this.isListNum = 5
+ }
+ }
+
+ aboutToAppear(): void {
+ this.listener.on('change', this.onPortrait.bind(this))
+ this.initPickParms()
+ this.deviceSelectSession = AppStorage.get('deviceSelectSession');
+ this.devListInfo();
+ }
+
+ aboutToDisappear(): void {
+ this.listener.off('change', this.onPortrait)
+ }
+
+ build() {
+ Column() {
+ Row() {
+ Text(this.title)
+ .fontSize(24)
+ .fontWeight(500)
+ .onClick(() => {
+ let arr: string[] = []
+ this.deviceList.forEach((item) => {
+ arr.push(item.device.deviceId)
+ arr = Array.from(new Set(arr))
+ })
+ })
+ Image($r('app.media.close')).width(40).height(40)
+ .onClick(() => {
+ this.cancel()
+ })
+ }.justifyContent(FlexAlign.SpaceBetween)
+ .width('100%')
+
+ if (this.deviceList.length <= this.isListNum) {
+ ForEach(this.deviceList, (item: Data, index: number) => {
+ Column() {
+ Stack() {
+ Image(item.status == StatusType.TrustBinding ? $r('app.media.icon_ball_online') :
+ $r('app.media.icon_ball')).width(54)
+ Image(item.device.deviceType == 'PHONE' ? $r('app.media.phone') : $r('app.media.icon_pad')).width(30)
+ }
+ .width(54)
+ .height(54)
+ .borderRadius(54)
+
+ Text(item.device.deviceName)
+ .fontSize(12)
+ .textAlign(TextAlign.Center)
+ }
+ .width(68)
+ .height(92)
+ .position({
+ x: this.calcPositionX(index) - 34,
+ y: this.calcPositionY(index) - 46
+ })
+ .onClick(() => {
+ if (item.status == StatusType.TrustBinding) {
+ this.sendData(item.device.deviceId, item.device.networkId, item.device.deviceName)
+ }
+ })
+ .onDrop((event: DragEvent, extraParams?: string | undefined) => {
+ this.showPhone = Visibility.Visible
+ this.bindTarget(item, index)
+ console.info('======onDrop onDrop:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ })
+ Column() {
+ Stack() {
+ Image($r('app.media.iocn_phone_self')).width(54).draggable(false)
+ Image($r('app.media.phone')).width(30).draggable(false)
+ }
+ .width(54)
+ .height(54)
+ .borderRadius(54)
+
+ Text($r('app.string.local_machine'))
+ .fontSize(12)
+ .textAlign(TextAlign.Center)
+ }
+ .width(68)
+ .height(92)
+ .position({
+ x: this.centerX - 34,
+ y: this.centerY - 46
+ })
+ .visibility(this.showPhone)
+ .draggable(true)
+ .onDragStart((event) => {
+ this.showPhone = Visibility.Hidden
+ console.info('======onDrop onDragStart:' + JSON.stringify(event));
+ return this.CustomBuilder()
+ })
+ .onDragEnter((event: DragEvent, extraParams?: string | undefined) => {
+ this.showPhone = Visibility.Hidden
+ console.info('======onDrop onDragEnter:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDragMove((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDragMove:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDrop((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDrop:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDragEnd((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDragEnd:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ } else {
+ Grid(this.scroller) {
+ ForEach(this.deviceList, (item: Data, index: number) => {
+ GridItem() {
+ Column() {
+ Stack() {
+ Image(item.status == StatusType.TrustBinding ? $r('app.media.icon_ball_online') :
+ $r('app.media.icon_ball')).width(54).draggable(false)
+ Image(item.device.deviceType == 'PHONE' ? $r('app.media.phone') : $r('app.media.icon_pad'))
+ .width(30)
+ .draggable(false)
+ }
+ .width(54)
+ .height(54)
+ .borderRadius(54)
+
+ Text(item.device.deviceName)
+ .fontSize(12)
+ .textAlign(TextAlign.Center)
+ }
+ .width(68)
+ .height(92)
+ .onClick(() => {
+ if (item.status == StatusType.TrustBinding) {
+ this.sendData(item.device.deviceId, item.device.networkId, item.device.deviceName)
+ } else {
+ this.bindTarget(item, index)
+ }
+ })
+ }
+ .draggable(true)
+ .onDragStart((event) => {
+ console.info('======onDrop onDragStart:' + JSON.stringify(event));
+ })
+ .onDragEnter((event: DragEvent, extraParams?: string | undefined) => {
+
+ console.info('======onDrop onDragEnter:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDragMove((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDragMove:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDrop((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDrop:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .onDragEnd((event: DragEvent, extraParams?: string | undefined) => {
+ console.info('======onDrop onDragEnd:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ })
+ }
+ .columnsTemplate('1fr 1fr 1fr 1fr 1fr')
+ .columnsGap(10)
+ .rowsGap(10)
+ .friction(0.6)
+ .enableScrollInteraction(true)
+ .supportAnimation(false)
+ .multiSelectable(false)
+ .edgeEffect(EdgeEffect.Spring)
+ .scrollBar(BarState.On)
+ .scrollBarColor(Color.Grey)
+ .scrollBarWidth(4)
+ .width('100%')
+ .layoutWeight(1)
+ }
+ }
+ .onDrop((event: DragEvent, extraParams?: string | undefined) => {
+ this.showPhone = Visibility.Visible
+ console.info('======onDrop onDrop:' + JSON.stringify(event), JSON.stringify(extraParams));
+ })
+ .width('100%')
+ .height('100%')
+ .backgroundColor(Color.White)
+ .borderRadius({ topLeft: 20, topRight: 20 })
+ .padding({ bottom: 0, left: 10, right: 10 })
+ .onClick(() => {
+ if (this.isAutoCancel) {
+ this.cancel();
+ }
+ })
+ .onAreaChange((oldValue, newValue) => {
+ this.centerX = Number(newValue.width) / 2
+ if (this.isLandscape) {
+ this.radius = Number(newValue.height) - 90
+ this.centerY = Number(newValue.height) - 20
+ } else {
+ this.radius = Math.min(Number(newValue.width), Number(newValue.height)) * 0.4
+ this.centerY = this.radius + 90
+ }
+ })
+ .visibility(this.showFlag)
+ .transition(TransitionEffect.OPACITY.animation({ duration: anmDuration })
+ .combine(TransitionEffect.translate({ y: 100 })))
+
+ }
+}
\ No newline at end of file
diff --git a/display/entry/src/main/module.json b/display/entry/src/main/module.json
index a1e04e78ecca004263b1e98ee1daf97b7f63eeda..c4d6963c456b2e5e84f75b2fcc2deb3929b0e39e 100644
--- a/display/entry/src/main/module.json
+++ b/display/entry/src/main/module.json
@@ -67,6 +67,15 @@
"label": "$string:ServiceExtAbility_label",
"exported": true,
"type": "sysDialog/common"
+ },
+ {
+ "name": "com.ohos.devicemanagerui.picker.DeviceSelectAbility",
+ "srcEntrance": "./ets/UIExtAbility/picker/DeviceSelectAbility.ets",
+ "description": "$string:ServiceExtAbility_desc",
+ "icon": "$media:icon",
+ "label": "$string:ServiceExtAbility_label",
+ "exported": true,
+ "type": "sysDialog/common"
}
],
"requestPermissions": [
@@ -78,6 +87,9 @@
},
{
"name": "ohos.permission.PRIVACY_WINDOW"
+ },
+ {
+ "name": "ohos.permission.DISTRIBUTED_DATASYNC"
}
],
"metadata": [
diff --git a/display/entry/src/main/resources/base/media/background.png b/display/entry/src/main/resources/base/media/background.png
new file mode 100644
index 0000000000000000000000000000000000000000..f939c9fa8cc8914832e602198745f592a0dfa34d
Binary files /dev/null and b/display/entry/src/main/resources/base/media/background.png differ
diff --git a/display/entry/src/main/resources/base/media/background_picker.png b/display/entry/src/main/resources/base/media/background_picker.png
new file mode 100644
index 0000000000000000000000000000000000000000..4c7a3509d2610a3749ffefab527ad247277a5c3e
Binary files /dev/null and b/display/entry/src/main/resources/base/media/background_picker.png differ
diff --git a/display/entry/src/main/resources/base/media/close.png b/display/entry/src/main/resources/base/media/close.png
new file mode 100644
index 0000000000000000000000000000000000000000..c72a52014d43419fc7330db489e9685c7f65748d
Binary files /dev/null and b/display/entry/src/main/resources/base/media/close.png differ
diff --git a/display/entry/src/main/resources/base/media/foreground.png b/display/entry/src/main/resources/base/media/foreground.png
new file mode 100644
index 0000000000000000000000000000000000000000..4483ddad1f079e1089d685bd204ee1cfe1d01902
Binary files /dev/null and b/display/entry/src/main/resources/base/media/foreground.png differ
diff --git a/display/entry/src/main/resources/base/media/icon_background.png b/display/entry/src/main/resources/base/media/icon_background.png
new file mode 100644
index 0000000000000000000000000000000000000000..e1492162570336840dc0337f2aa0dd9eec0a74d3
Binary files /dev/null and b/display/entry/src/main/resources/base/media/icon_background.png differ
diff --git a/display/entry/src/main/resources/base/media/icon_background_light.png b/display/entry/src/main/resources/base/media/icon_background_light.png
new file mode 100644
index 0000000000000000000000000000000000000000..5c9344358225c1a9a30cace297ffa31fab0a5dd4
Binary files /dev/null and b/display/entry/src/main/resources/base/media/icon_background_light.png differ
diff --git a/display/entry/src/main/resources/base/media/icon_ball.png b/display/entry/src/main/resources/base/media/icon_ball.png
new file mode 100644
index 0000000000000000000000000000000000000000..f7eeaf1cb072513be6c9af52c8e477a20d05be81
Binary files /dev/null and b/display/entry/src/main/resources/base/media/icon_ball.png differ
diff --git a/display/entry/src/main/resources/base/media/icon_ball_online.png b/display/entry/src/main/resources/base/media/icon_ball_online.png
new file mode 100644
index 0000000000000000000000000000000000000000..5a5562cff051b78e51a55768556f528cadf57fdf
Binary files /dev/null and b/display/entry/src/main/resources/base/media/icon_ball_online.png differ
diff --git a/display/entry/src/main/resources/base/media/icon_pad.png b/display/entry/src/main/resources/base/media/icon_pad.png
new file mode 100644
index 0000000000000000000000000000000000000000..29b9a0607f76551203c2e6d325004f201390914d
Binary files /dev/null and b/display/entry/src/main/resources/base/media/icon_pad.png differ
diff --git a/display/entry/src/main/resources/base/media/img.png b/display/entry/src/main/resources/base/media/img.png
new file mode 100644
index 0000000000000000000000000000000000000000..fb7633cf7c637d0631d04d2bfdb48947944298d0
Binary files /dev/null and b/display/entry/src/main/resources/base/media/img.png differ
diff --git a/display/entry/src/main/resources/base/media/img_select.png b/display/entry/src/main/resources/base/media/img_select.png
new file mode 100644
index 0000000000000000000000000000000000000000..35a077a9929d611dd91af9fcf2609de28954501f
Binary files /dev/null and b/display/entry/src/main/resources/base/media/img_select.png differ
diff --git a/display/entry/src/main/resources/base/media/iocn_phone_self.png b/display/entry/src/main/resources/base/media/iocn_phone_self.png
new file mode 100644
index 0000000000000000000000000000000000000000..bf74b558b43a41bcb977ede8f93be8430fbcaa6f
Binary files /dev/null and b/display/entry/src/main/resources/base/media/iocn_phone_self.png differ
diff --git a/display/entry/src/main/resources/base/media/phone.png b/display/entry/src/main/resources/base/media/phone.png
new file mode 100644
index 0000000000000000000000000000000000000000..7f0e68f30a71c577223e3c3fd114afae5b399221
Binary files /dev/null and b/display/entry/src/main/resources/base/media/phone.png differ
diff --git a/display/entry/src/main/resources/base/media/startIcon.png b/display/entry/src/main/resources/base/media/startIcon.png
new file mode 100644
index 0000000000000000000000000000000000000000..205ad8b5a8a42e8762fbe4899b8e5e31ce822b8b
Binary files /dev/null and b/display/entry/src/main/resources/base/media/startIcon.png differ
diff --git a/display/entry/src/main/resources/base/media/status.png b/display/entry/src/main/resources/base/media/status.png
new file mode 100644
index 0000000000000000000000000000000000000000..fff3a2d0045dafea80ffd0b85027edcea0ac3383
Binary files /dev/null and b/display/entry/src/main/resources/base/media/status.png differ
diff --git a/display/entry/src/main/resources/base/profile/main_pages.json b/display/entry/src/main/resources/base/profile/main_pages.json
index cfe70b3426b3acfab0140015e264a91c172778cb..4b73c7b4f94e56a3193e1646baf4e69dca53b019 100644
--- a/display/entry/src/main/resources/base/profile/main_pages.json
+++ b/display/entry/src/main/resources/base/profile/main_pages.json
@@ -6,6 +6,7 @@
"pages/BluetoothDialog",
"pages/ConfirmDialogWearable",
"pages/PinDialogWearable",
- "pages/InputPinDialogWearable"
+ "pages/InputPinDialogWearable",
+ "pages/picker/DeviceSelect"
]
}
diff --git a/display/entry/src/main/resources/es_US/element/string.json b/display/entry/src/main/resources/es_US/element/string.json
index b09c22c0768d461208977003d47ae661f71b8693..15b5fab8d72c455a28e7374906a6db3997ad979d 100644
--- a/display/entry/src/main/resources/es_US/element/string.json
+++ b/display/entry/src/main/resources/es_US/element/string.json
@@ -48,6 +48,10 @@
"attr":{
"priority":"translate"
}
+ },
+ {
+ "name":"local_machine",
+ "value":"local machine"
}
]
}
\ No newline at end of file
diff --git a/display/entry/src/main/resources/zh_CN/element/string.json b/display/entry/src/main/resources/zh_CN/element/string.json
index 90d642d9e5e3417e594b968c7f7e579f09280cbd..eee4e696c98987132ac88f216f04a1c28d4a99e4 100644
--- a/display/entry/src/main/resources/zh_CN/element/string.json
+++ b/display/entry/src/main/resources/zh_CN/element/string.json
@@ -104,6 +104,10 @@
{
"name":"dm_password_error",
"value":"密码错误,连接失败。"
+ },
+ {
+ "name":"local_machine",
+ "value":"本机"
}
]
}
\ No newline at end of file
diff --git a/interfaces/inner_kits/native_cpp/include/dm_device_info.h b/interfaces/inner_kits/native_cpp/include/dm_device_info.h
index b98d588955456e1d9e538f8635dbde31194703f7..aa21ac17b041496dd9df7f1dea34ae1b6de71623 100644
--- a/interfaces/inner_kits/native_cpp/include/dm_device_info.h
+++ b/interfaces/inner_kits/native_cpp/include/dm_device_info.h
@@ -208,6 +208,11 @@ DmDeviceBasicInfo {
* NetworkId of the device.
*/
char networkId[DM_MAX_DEVICE_ID_LEN] = {0};
+ /**
+ * Extra data of the device.
+ * include json keys: "CUSTOM_DATA"
+ */
+ std::string extraData;
} DmDeviceBasicInfo;
/**
diff --git a/interfaces/kits/js4.0/include/dm_native_util.h b/interfaces/kits/js4.0/include/dm_native_util.h
index 68d0edb9affc0b81c5c52f674ed0565d247f4736..38a4158e37f230f19566b64d797e48231d2b497b 100644
--- a/interfaces/kits/js4.0/include/dm_native_util.h
+++ b/interfaces/kits/js4.0/include/dm_native_util.h
@@ -87,7 +87,8 @@ void DmDeviceIconInfoToJs(const napi_env &env, const DmDeviceIconInfo &deviceIco
void DmDeviceProfileInfoToJsArray(const napi_env &env, const std::vector &devInfos,
napi_value &arrayResult);
bool JsToDmDeviceProfileInfos(const napi_env &env, const napi_value &jsObj, std::vector &devInfos);
-
+void JsToDiscoveryParam(const napi_env &env, const napi_value &object,
+ std::map &discParam);
} // namespace DistributedHardware
} // namespace OHOS
#endif // OHOS_DM_NATIVE_UTIL_H
diff --git a/interfaces/kits/js4.0/include/native_devicemanager_js.h b/interfaces/kits/js4.0/include/native_devicemanager_js.h
index 0bd52b05dea42d6d455c389fe734c75137a6770a..02c4739777dde6605b23e170548f929d85ccfb96 100644
--- a/interfaces/kits/js4.0/include/native_devicemanager_js.h
+++ b/interfaces/kits/js4.0/include/native_devicemanager_js.h
@@ -334,8 +334,8 @@ public:
private:
static void ReleasePublishCallback(std::string &bundleName);
static void ReleaseDiscoveryCallback(std::string &bundleName);
- static void LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName, std::string &extra,
- uint32_t subscribeId);
+ static void LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName,
+ std::map discParam, std::string &extra, uint32_t subscribeId);
static void ClearBundleCallbacks(std::string &bundleName);
static napi_value JsOffFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[]);
static napi_value JsOnFrench(napi_env env, int32_t num, napi_value thisVar, napi_value argv[]);
diff --git a/interfaces/kits/js4.0/src/dm_native_util.cpp b/interfaces/kits/js4.0/src/dm_native_util.cpp
index 711ebe4c5f1a0d81bdb2ae4b1819a4f6e25a4ed7..91d06911debe71488143e41c24f3e3f9281d5114 100644
--- a/interfaces/kits/js4.0/src/dm_native_util.cpp
+++ b/interfaces/kits/js4.0/src/dm_native_util.cpp
@@ -47,7 +47,8 @@ const int32_t MAX_OBJECT_LEN = 4096;
void JsObjectToString(const napi_env &env, const napi_value &object, const std::string &fieldStr,
char *dest, const int32_t destLen)
{
- if (dest == nullptr || destLen < 0 || destLen > MAX_OBJECT_LEN) {
+ if (dest == nullptr || destLen < 0 || (destLen > MAX_OBJECT_LEN && fieldStr != CUSTOM_DESCRIPTION) ||
+ destLen > DM_NAPI_DESCRIPTION_BUF_LENGTH) {
return;
}
bool hasProperty = false;
@@ -292,6 +293,7 @@ void DmDeviceBasicToJsObject(napi_env env, const DmDeviceBasicInfo &devInfo, nap
SetValueUtf8String(env, "deviceName", devInfo.deviceName, result);
std::string deviceType = GetDeviceTypeById(static_cast(devInfo.deviceTypeId));
SetValueUtf8String(env, "deviceType", deviceType.c_str(), result);
+ SetValueUtf8String(env, "extraData", devInfo.extraData.c_str(), result);
}
void JsToDmPublishInfo(const napi_env &env, const napi_value &object, DmPublishInfo &info)
@@ -431,6 +433,17 @@ void JsToDmDiscoveryExtra(const napi_env &env, const napi_value &object, std::st
LOGI("JsToDmDiscoveryExtra, extra :%{public}s", extra.c_str());
}
+void JsToDiscoveryParam(const napi_env &env, const napi_value &object,
+ std::map &discParam)
+{
+ char customData[DM_NAPI_BUF_LENGTH] = "";
+ JsObjectToString(env, object, "CUSTOM_DATA", customData, sizeof(customData));
+ discParam.insert(std::pair(PARAM_KEY_CUSTOM_DATA, customData));
+ char capability[DM_NAPI_BUF_LENGTH] = "";
+ JsObjectToString(env, object, "DISC_CAPABILITY", capability, sizeof(capability));
+ discParam.insert(std::pair(PARAM_KEY_DISC_CAPABILITY, capability));
+}
+
void InsertMapParames(nlohmann::json &bindParamObj, std::map &bindParamMap)
{
LOGI("Insert map parames start");
diff --git a/interfaces/kits/js4.0/src/native_devicemanager_js.cpp b/interfaces/kits/js4.0/src/native_devicemanager_js.cpp
index ed6317237145d77e1cb048b41433710805b444d5..48fe2775bc6a22d56d821e315b3142950aa28ea8 100644
--- a/interfaces/kits/js4.0/src/native_devicemanager_js.cpp
+++ b/interfaces/kits/js4.0/src/native_devicemanager_js.cpp
@@ -1482,8 +1482,8 @@ napi_value DeviceManagerNapi::GetDeviceType(napi_env env, napi_callback_info inf
return result;
}
-void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName, std::string &extra,
- uint32_t subscribeId)
+void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, std::string &bundleName,
+ std::map discParam, std::string &extra, uint32_t subscribeId)
{
std::shared_ptr discoveryCallback = nullptr;
{
@@ -1497,7 +1497,10 @@ void DeviceManagerNapi::LockDiscoveryCallbackMutex(napi_env env, std::string &bu
}
}
uint64_t tokenId = OHOS::IPCSkeleton::GetSelfTokenID();
- int32_t ret = DeviceManager::GetInstance().StartDeviceDiscovery(bundleName, tokenId, extra, discoveryCallback);
+ discParam.insert(std::pair(PARAM_KEY_SUBSCRIBE_ID, std::to_string(tokenId)));
+ std::map filterOps;
+ filterOps.insert(std::pair(PARAM_KEY_FILTER_OPTIONS, extra));
+ int32_t ret = DeviceManager::GetInstance().StartDiscovering(bundleName, discParam, filterOps, discoveryCallback);
if (ret != 0) {
LOGE("Discovery failed, bundleName %{public}s, ret %{public}d", bundleName.c_str(), ret);
CreateBusinessError(env, ret);
@@ -1510,6 +1513,7 @@ napi_value DeviceManagerNapi::StartDeviceDiscover(napi_env env, napi_callback_in
{
LOGI("StartDeviceDiscover in");
std::string extra = "";
+ std::map discParam;
napi_value result = nullptr;
napi_value thisVar = nullptr;
size_t argcNum = 0;
@@ -1526,11 +1530,13 @@ napi_value DeviceManagerNapi::StartDeviceDiscover(napi_env env, napi_callback_in
if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
return nullptr;
}
+ JsToDiscoveryParam(env, argv[DM_NAPI_ARGS_ZERO], discParam);
} else if (argcNum == DM_NAPI_ARGS_TWO) {
GET_PARAMS(env, info, DM_NAPI_ARGS_TWO);
if (!JsToDiscoverTargetType(env, argv[DM_NAPI_ARGS_ZERO], discoverTargetType) || discoverTargetType != 1) {
return nullptr;
}
+ JsToDiscoveryParam(env, argv[DM_NAPI_ARGS_ZERO], discParam);
napi_valuetype objectType = napi_undefined;
napi_typeof(env, argv[DM_NAPI_ARGS_ONE], &objectType);
if (!(CheckArgsType(env, objectType == napi_object, "filterOptions", "object or undefined"))) {
@@ -1538,7 +1544,7 @@ napi_value DeviceManagerNapi::StartDeviceDiscover(napi_env env, napi_callback_in
}
JsToDmDiscoveryExtra(env, argv[DM_NAPI_ARGS_ONE], extra);
}
- LockDiscoveryCallbackMutex(env, deviceManagerWrapper->bundleName_, extra, subscribeId);
+ LockDiscoveryCallbackMutex(env, deviceManagerWrapper->bundleName_, discParam, extra, subscribeId);
napi_get_undefined(env, &result);
return result;
}
diff --git a/sa_profile/device_manager.cfg b/sa_profile/device_manager.cfg
index 4a495502fd274812e3b69b1b2725dabc1bf0279c..f99cf2b500c38c6e3b900b6d2767c110bae07d55 100644
--- a/sa_profile/device_manager.cfg
+++ b/sa_profile/device_manager.cfg
@@ -30,6 +30,7 @@
"ohos.permission.ACCESS_BLUETOOTH",
"ohos.permission.MANAGE_BLUETOOTH",
"ohos.permission.MANAGE_SETTINGS",
+ "ohos.permission.MANAGE_SOFTBUS_NETWORK",
"ohos.permission.START_SYSTEM_DIALOG",
"ohos.permission.INTERACT_ACROSS_LOCAL_ACCOUNTS",
"ohos.permission.GET_BUNDLE_RESOURCES",
@@ -40,6 +41,9 @@
"ohos.permission.ACCESS_SERVICE_DP",
"ohos.permission.ACCESS_SENSING_WITH_ULTRASOUND"
],
+ "permission_acls" : [
+ "ohos.permission.MANAGE_SOFTBUS_NETWORK"
+ ],
"jobs" : {
"on-start" : "service:device_manager"
},
diff --git a/services/implementation/BUILD.gn b/services/implementation/BUILD.gn
index 3b442952cf48421faf737dc6629961b3fabd308e..6d20598cf1e268c65f16803b39064e11411b19d0 100644
--- a/services/implementation/BUILD.gn
+++ b/services/implementation/BUILD.gn
@@ -124,6 +124,7 @@ if (defined(ohos_lite)) {
"include/dependency/multipleuser",
"include/dependency/hichain",
"include/dependency/softbus",
+ "include/i18n",
"${common_path}/include",
"${common_path}/include/dfx",
"${common_path}/include/dfx/standard",
@@ -190,6 +191,7 @@ if (defined(ohos_lite)) {
"src/dependency/softbus/softbus_session.cpp",
"src/device_manager_service_impl.cpp",
"src/devicestate/dm_device_state_manager.cpp",
+ "src/i18n/dm_language_manager.cpp",
]
public_configs = [ ":devicemanagerserviceimpl_config" ]
diff --git a/services/implementation/include/authentication/dm_auth_manager.h b/services/implementation/include/authentication/dm_auth_manager.h
index 3aa067a63d6d82687f2db300eae7846a55c315b9..aef138cdf572f25766dea6d5156757ae0d4bfae3 100644
--- a/services/implementation/include/authentication/dm_auth_manager.h
+++ b/services/implementation/include/authentication/dm_auth_manager.h
@@ -499,7 +499,7 @@ private:
void JoinLnn(const std::string &deviceId);
int32_t CheckAuthParamVaild(const std::string &pkgName, int32_t authType, const std::string &deviceId,
const std::string &extra);
- int32_t CheckAuthParamVaildExtra(const std::string &extra);
+ int32_t CheckAuthParamVaildExtra(const std::string &extra, const std::string &deviceId);
bool CheckProcessNameInWhiteList(const std::string &processName);
void ProcessSourceMsg();
void ProcessSinkMsg();
@@ -582,6 +582,7 @@ private:
bool IsSinkMsgValid();
bool IsSourceMsgValid();
void ProcessReqPublicKey();
+ int32_t GetTokenIdByBundleName(int32_t userId, std::string &bundleName, int64_t &tokenId);
private:
std::shared_ptr softbusConnector_;
diff --git a/services/implementation/include/dependency/softbus/softbus_connector.h b/services/implementation/include/dependency/softbus/softbus_connector.h
index a12651e1e32fa17a6cdb419d52e062d5d1cf8243..293c285627bd82efce5c0a1208783e4b9bae2ef8 100644
--- a/services/implementation/include/dependency/softbus/softbus_connector.h
+++ b/services/implementation/include/dependency/softbus/softbus_connector.h
@@ -84,6 +84,13 @@ public:
* @tc.type: FUNC
*/
static void JoinLnnByHml(int32_t sessionId, int32_t sessionKeyId, int32_t remoteSessionKeyId);
+
+ /**
+ * @tc.name: SoftbusConnector::JoinLnnByHml
+ * @tc.desc: join lnn by session id
+ * @tc.type: FUNC
+ */
+ static void JoinLnnByHml(const int32_t sessionId);
public:
SoftbusConnector();
~SoftbusConnector();
diff --git a/services/implementation/include/dependency/softbus/softbus_session.h b/services/implementation/include/dependency/softbus/softbus_session.h
index 2e7be8f5712f2045cbaced3dbb18fd382056820d..289a9cd60e3ad756eff66cfc0b3039ea401a09ab 100644
--- a/services/implementation/include/dependency/softbus/softbus_session.h
+++ b/services/implementation/include/dependency/softbus/softbus_session.h
@@ -65,7 +65,7 @@ public:
* @tc.desc: Open HML AuthSession of the Softbus Session
* @tc.type: FUNC
*/
- int32_t OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool enable160m);
+ int32_t OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool isEnable160m);
/**
* @tc.name: SoftbusSession::CloseAuthSession
diff --git a/services/implementation/include/i18n/dm_language_manager.h b/services/implementation/include/i18n/dm_language_manager.h
new file mode 100644
index 0000000000000000000000000000000000000000..9cbc36243c5eee8c7765ffd500ca583b7bd529e1
--- /dev/null
+++ b/services/implementation/include/i18n/dm_language_manager.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2025 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.
+ */
+
+#ifndef OHOS_DM_LANGUAGE_MANAGER_H
+#define OHOS_DM_LANGUAGE_MANAGER_H
+
+#include
+#include
+
+#include "cJSON.h"
+#include "dm_single_instance.h"
+namespace OHOS {
+namespace DistributedHardware {
+
+class DmLanguageManager {
+ DM_DECLARE_SINGLE_INSTANCE_BASE(DmLanguageManager);
+
+public:
+ DmLanguageManager() {}
+ ~DmLanguageManager() {}
+ std::string GetSystemParam(const std::string &key);
+ void GetLocaleByLanguage(const std::string &language, std::set &localeSet);
+ std::string GetTextBySystemLocale(const cJSON *const textObj, const std::set &localeSet);
+ std::string GetTextBySystemLanguage(const std::string &text);
+};
+} // namespace DistributedHardware
+} // namespace OHOS
+#endif // OHOS_DM_LANGUAGE_MANAGER_H
diff --git a/services/implementation/src/authentication/dm_auth_manager.cpp b/services/implementation/src/authentication/dm_auth_manager.cpp
index 6bae0a4a8d5df352c63c17651b515256b9148115..00c4eb376617ef9eb4f32499b62638b04106c028 100644
--- a/services/implementation/src/authentication/dm_auth_manager.cpp
+++ b/services/implementation/src/authentication/dm_auth_manager.cpp
@@ -37,6 +37,7 @@
#include "dm_constants.h"
#include "dm_crypto.h"
#include "dm_dialog_manager.h"
+#include "dm_language_manager.h"
#include "dm_log.h"
#include "dm_radar_helper.h"
#include "dm_random.h"
@@ -168,14 +169,6 @@ int32_t DmAuthManager::CheckAuthParamVaild(const std::string &pkgName, int32_t a
return ERR_DM_AUTH_BUSINESS_BUSY;
}
- if (!softbusConnector_->HaveDeviceInMap(deviceId)) {
- LOGE("CheckAuthParamVaild failed, the discoveryDeviceInfoMap_ not have this device.");
- listener_->OnAuthResult(processInfo_, peerTargetId_.deviceId, "", STATUS_DM_AUTH_DEFAULT,
- ERR_DM_INPUT_PARA_INVALID);
- listener_->OnBindResult(processInfo_, peerTargetId_, ERR_DM_INPUT_PARA_INVALID, STATUS_DM_AUTH_DEFAULT, "");
- return ERR_DM_INPUT_PARA_INVALID;
- }
-
if ((authType == AUTH_TYPE_IMPORT_AUTH_CODE) && (!IsAuthCodeReady(pkgName))) {
LOGE("Auth code not exist.");
listener_->OnAuthResult(processInfo_, peerTargetId_.deviceId, "", STATUS_DM_AUTH_DEFAULT,
@@ -186,9 +179,18 @@ int32_t DmAuthManager::CheckAuthParamVaild(const std::string &pkgName, int32_t a
return DM_OK;
}
-int32_t DmAuthManager::CheckAuthParamVaildExtra(const std::string &extra)
+int32_t DmAuthManager::CheckAuthParamVaildExtra(const std::string &extra, const std::string &deviceId)
{
nlohmann::json jsonObject = nlohmann::json::parse(extra, nullptr, false);
+ if ((jsonObject.is_discarded() || !IsString(jsonObject, PARAM_KEY_CONN_SESSIONTYPE) ||
+ jsonObject[PARAM_KEY_CONN_SESSIONTYPE].get() != CONN_SESSION_TYPE_HML) &&
+ !softbusConnector_->HaveDeviceInMap(deviceId)) {
+ LOGE("CheckAuthParamVaild failed, the discoveryDeviceInfoMap_ not have this device.");
+ listener_->OnAuthResult(processInfo_, peerTargetId_.deviceId, "", STATUS_DM_AUTH_DEFAULT,
+ ERR_DM_INPUT_PARA_INVALID);
+ listener_->OnBindResult(processInfo_, peerTargetId_, ERR_DM_INPUT_PARA_INVALID, STATUS_DM_AUTH_DEFAULT, "");
+ return ERR_DM_INPUT_PARA_INVALID;
+ }
if (jsonObject.is_discarded()) {
return DM_OK;
}
@@ -251,8 +253,10 @@ void DmAuthManager::GetAuthParam(const std::string &pkgName, int32_t authType,
char localDeviceId[DEVICE_UUID_LENGTH] = {0};
GetDevUdid(localDeviceId, DEVICE_UUID_LENGTH);
std::string localUdid = static_cast(localDeviceId);
- authRequestContext_->hostPkgName = pkgName;
- authRequestContext_->hostPkgLabel = GetBundleLable(pkgName);
+ std::string realPkgName = GetSubStr(pkgName, PICKER_PROXY_SPLIT, 1);
+ realPkgName = realPkgName.empty() ? pkgName : realPkgName;
+ authRequestContext_->hostPkgName = realPkgName;
+ authRequestContext_->hostPkgLabel = GetBundleLable(realPkgName);
authRequestContext_->authType = authType;
authRequestContext_->localDeviceName = softbusConnector_->GetLocalDeviceName();
authRequestContext_->localDeviceTypeId = softbusConnector_->GetLocalDeviceTypeId();
@@ -263,6 +267,9 @@ void DmAuthManager::GetAuthParam(const std::string &pkgName, int32_t authType,
uint32_t tokenId = 0 ;
MultipleUserConnector::GetTokenIdAndForegroundUserId(tokenId, authRequestContext_->localUserId);
authRequestContext_->tokenId = static_cast(tokenId);
+ if (realPkgName != pkgName) {
+ GetTokenIdByBundleName(authRequestContext_->localUserId, realPkgName, authRequestContext_->tokenId);
+ }
authRequestContext_->localAccountId =
MultipleUserConnector::GetOhosAccountIdByUserId(authRequestContext_->localUserId);
authRequestContext_->isOnline = false;
@@ -288,7 +295,8 @@ void DmAuthManager::ParseJsonObject(nlohmann::json jsonObject)
authRequestContext_->appOperation = jsonObject[APP_OPERATION_KEY].get();
}
if (IsString(jsonObject, CUSTOM_DESCRIPTION_KEY)) {
- authRequestContext_->customDesc = jsonObject[CUSTOM_DESCRIPTION_KEY].get();
+ authRequestContext_->customDesc = DmLanguageManager::GetInstance().
+ GetTextBySystemLanguage(jsonObject[CUSTOM_DESCRIPTION_KEY].get());
}
if (IsString(jsonObject, APP_THUMBNAIL)) {
authRequestContext_->appThumbnail = jsonObject[APP_THUMBNAIL].get();
@@ -398,7 +406,7 @@ int32_t DmAuthManager::AuthenticateDevice(const std::string &pkgName, int32_t au
LOGE("DmAuthManager::AuthenticateDevice failed, param is invaild.");
return ret;
}
- ret = CheckAuthParamVaildExtra(extra);
+ ret = CheckAuthParamVaildExtra(extra, deviceId);
if (ret != DM_OK) {
LOGE("CheckAuthParamVaildExtra failed, param is invaild.");
return ret;
@@ -3213,5 +3221,18 @@ void DmAuthManager::JoinLnn(const std::string &deviceId)
}
softbusConnector_->JoinLnn(deviceId);
}
+
+int32_t DmAuthManager::GetTokenIdByBundleName(int32_t userId, std::string &bundleName, int64_t &tokenId)
+{
+ int32_t ret = AppManager::GetInstance().GetNativeTokenIdByName(bundleName, tokenId);
+ if (ret == DM_OK) {
+ return DM_OK;
+ }
+ ret = AppManager::GetInstance().GetHapTokenIdByName(userId, bundleName, 0, tokenId);
+ if (ret != DM_OK) {
+ LOGE("get tokenId by bundleName failed %{public}s", GetAnonyString(bundleName).c_str());
+ }
+ return ret;
+}
} // namespace DistributedHardware
} // namespace OHOS
diff --git a/services/implementation/src/dependency/softbus/softbus_connector.cpp b/services/implementation/src/dependency/softbus/softbus_connector.cpp
index f93432802d1a12ccf4767e00364a5757eefc6014..aa13c06f425ed67a0e43e456339d7cac45def86c 100644
--- a/services/implementation/src/dependency/softbus/softbus_connector.cpp
+++ b/services/implementation/src/dependency/softbus/softbus_connector.cpp
@@ -116,6 +116,18 @@ void SoftbusConnector::JoinLnnByHml(int32_t sessionId, int32_t sessionKeyId, int
}
}
+void SoftbusConnector::JoinLnnByHml(const int32_t sessionId)
+{
+ LOGI("start, JoinLnnByHml sessionId: %{public}d.", sessionId);
+ ConnectionAddr addrInfo;
+ addrInfo.type = CONNECTION_ADDR_SESSION;
+ addrInfo.info.session.sessionId = sessionId;
+ int32_t ret = ::JoinLNN(DM_PKG_NAME, &addrInfo, OnSoftbusJoinLNNResult);
+ if (ret != DM_OK) {
+ LOGE("[SOFTBUS]JoinLNN failed, ret: %{public}d.", ret);
+ }
+}
+
int32_t SoftbusConnector::GetUdidByNetworkId(const char *networkId, std::string &udid)
{
LOGI("start, networkId: %{public}s.", GetAnonyString(std::string(networkId)).c_str());
diff --git a/services/implementation/src/dependency/softbus/softbus_session.cpp b/services/implementation/src/dependency/softbus/softbus_session.cpp
index 4c17ce3ae10f4f28ee3c93c427d5cd0f15723637..76d0081405b7fe810c91484d3ac9df52e6c6444e 100644
--- a/services/implementation/src/dependency/softbus/softbus_session.cpp
+++ b/services/implementation/src/dependency/softbus/softbus_session.cpp
@@ -114,7 +114,7 @@ int32_t SoftbusSession::OpenAuthSession(const std::string &deviceId)
return sessionId;
}
-int32_t SoftbusSession::OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool enable160m)
+int32_t SoftbusSession::OpenAuthSessionWithPara(const std::string &deviceId, int32_t actionId, bool isEnable160m)
{
#ifdef DEVICE_MANAGER_COMMON_FLAG
LOGE("[SOFTBUS] OpenAuthSessionWithPara no implement");
@@ -124,7 +124,7 @@ int32_t SoftbusSession::OpenAuthSessionWithPara(const std::string &deviceId, int
LinkPara para;
para.type = PARA_ACTION;
para.action.actionId = actionId;
- para.enable160M = enable160m;
+ para.enable160M = isEnable160m;
para.accountInfo = false;
int32_t sessionId = ::OpenAuthSessionWithPara(DM_SESSION_NAME, ¶);
if (sessionId < 0) {
diff --git a/services/implementation/src/i18n/dm_language_manager.cpp b/services/implementation/src/i18n/dm_language_manager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77f080ee5c412b3ddfe41d4c13262a97bb2aee2b
--- /dev/null
+++ b/services/implementation/src/i18n/dm_language_manager.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2025 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 "dm_language_manager.h"
+
+#include "cJSON.h"
+#include