1/* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import prompt from '@ohos.prompt' 17import window from '@ohos.window' 18import display from '@ohos.display' 19import deviceManager from '@ohos.distributedHardware.deviceManager' 20import Logger from '../data/Logger' 21import DataModel from '../data/DataModel' 22import RemoteDeviceModel from '../data/RemoteDeviceModel' 23import { distributedDataModel } from '../data/DistributedDataModel' 24import { dmsConst } from '../data/DmsConst' 25import TitleBar from '../component/TitleBar' 26 27const TAG: string = 'Index' 28 29@Entry 30@Component 31struct Index { 32 @State documents: Array<DataModel> = [] 33 @State screenWidth: number = 0 34 @State screenHeight: number = 0 35 @State imageTranslate: number = 195 // 动画在中间 36 @State duration: number = dmsConst.CONVERT_MILLISECOND 37 @State status: Array<boolean> = new Array() 38 @State @Watch('changeDevices') devices: Array<deviceManager.DeviceInfo> = [] 39 @State remoteDeviceModel: RemoteDeviceModel = new RemoteDeviceModel() 40 @State isStart: boolean = false 41 @State isShowDialog: boolean = true 42 @State dialogShow: boolean = false 43 @State deviceText: string = '' 44 @State screenSizeText: string = '' 45 @State offlineText: string = '' 46 @State onlineText: string = '' 47 @State allCompleteText: string = '' 48 @StorageLink('deviceId') deviceId: string = '' 49 @StorageLink('isFA') isFA: string = '' 50 private deviceTag: number = 0 51 private deleteDevices: Array<deviceManager.DeviceInfo> = [] 52 private countCallBack: number = 0 53 private tempDocuments: Array<DataModel> = [] 54 55 @Builder statusBuild(resource: Resource) { 56 Image(resource) 57 .width(15) 58 .height(15) 59 .margin({ right: 40 }) 60 } 61 62 build() { 63 Column() { 64 TitleBar({ 65 devices: $devices, 66 remoteDeviceModel: $remoteDeviceModel, 67 dialogShow: $dialogShow, 68 isStart: this.isStart 69 }) 70 71 Image($r('app.media.people')) 72 .width(80) 73 .height(80) 74 .margin({ top: 50, bottom: 20 }) 75 .alignSelf(ItemAlign.Start) 76 .translate({ x: this.imageTranslate }) 77 78 Text($r('app.string.MainAbility_label')) 79 .fontSize(20) 80 .fontColor('#D7D6D6') 81 .alignSelf(ItemAlign.Center) 82 83 Scroll() { 84 Column() { 85 ForEach(this.devices, (item, index) => { 86 Row() { 87 Column() { 88 if (this.devices.length >= index + dmsConst.ONE) { 89 Text(`${index}${this.deviceText}${this.devices[index].deviceId}`) 90 .fontSize(18) 91 .fontWeight(500) 92 } 93 if (index === 0) { 94 Text(`${this.screenSizeText}${fp2px(this.screenWidth)} * ${this.screenHeight}`) 95 .fontSize(17) 96 } 97 if (index !== 0 && this.documents.length >= index && this.documents[index-dmsConst.ONE]) { 98 Text(`${this.screenSizeText}${this.documents[index-dmsConst.ONE].screenSize}`) 99 .fontSize(17) 100 } 101 } 102 .width('85%') 103 .margin({ left: 20 }) 104 .alignItems(HorizontalAlign.Start) 105 106 Blank() 107 Column() { 108 if (this.status.length > index && !this.status[index]) { 109 this.statusBuild($r('app.media.red')) 110 } else { 111 this.statusBuild($r('app.media.green')) 112 } 113 } 114 .width('10%') 115 } 116 .width('100%') 117 .constraintSize({ minHeight: 120 }) 118 .alignSelf(ItemAlign.Start) 119 .backgroundColor('#F6F8F8') 120 .borderRadius(40) 121 .margin({ top: 20 }) 122 }, item => item.deviceId) 123 } 124 .width('100%') 125 } 126 .constraintSize({ maxHeight: '53%' }) 127 .margin({ top: 10 }) 128 129 if (!this.isStart) { 130 Button() { 131 Text($r('app.string.start')) 132 .fontSize(30) 133 .fontColor(Color.White) 134 } 135 .key('startBtn') 136 .width('40%') 137 .height(60) 138 .margin({ top: 100 }) 139 .backgroundColor('#0D9EFA') 140 .alignSelf(ItemAlign.Center) 141 .onClick(() => { 142 Logger.info(TAG, `onClick start devices: ${JSON.stringify(this.devices)}`) 143 this.registerDevice() 144 this.isStart = true 145 Logger.info(TAG, 'onClick end') 146 }) 147 } 148 } 149 .justifyContent(FlexAlign.Start) 150 .width('100%') 151 .height('100%') 152 } 153 154 async convertResourceToString(resource: Resource) { 155 let context = getContext(this) as any 156 return await context.resourceManager.getString(resource) 157 } 158 159 changeDevices() { 160 this.status = this.devices.map(() => { 161 return false 162 }) 163 } 164 165 dataChangeCallback = () => { 166 this.countCallBack++ 167 Logger.info(TAG, `this.countCallBack = ${this.countCallBack}`) 168 if (this.countCallBack % dmsConst.TWO === dmsConst.ONE) { 169 return 170 } 171 Logger.info(TAG, `dataChangeCallback distributedObject = ${JSON.stringify(distributedDataModel.distributedObject)}`) 172 this.tempDocuments = distributedDataModel.distributedObject.documents 173 if (this.tempDocuments.length > 0) { 174 this.documents.push(this.tempDocuments[dmsConst.ZERO]) 175 } 176 if (this.status.length > this.deviceTag) { 177 this.status[this.deviceTag] = true 178 } 179 Logger.info(TAG, `dataChangeCallback this.deviceTag = ${this.deviceTag}`) 180 if (this.deviceTag < this.devices.length - dmsConst.ONE) { 181 this.startAbility(this.devices[++this.deviceTag].deviceId) 182 } else if (this.deviceTag === (this.devices.length - dmsConst.ONE) && this.isShowDialog) { 183 prompt.showToast({ message: this.allCompleteText }) 184 this.isShowDialog = false 185 this.isStart = false 186 } 187 Logger.info(TAG, `dataChangeCallback end`) 188 } 189 190 async aboutToAppear() { 191 Logger.info(TAG, 'aboutToAppear start') 192 this.deviceText = await this.convertResourceToString($r('app.string.device_id')) 193 this.screenSizeText = await this.convertResourceToString($r('app.string.record_screen_size')) 194 this.offlineText = await this.convertResourceToString($r('app.string.offline')) 195 this.onlineText = await this.convertResourceToString($r('app.string.online')) 196 this.allCompleteText = await this.convertResourceToString($r('app.string.all_device_complete')) 197 await this.onInit() 198 if (this.isFA === 'isFA') { 199 this.imageTranslate = 0 200 this.isStart = true 201 Logger.info(TAG, `aboutToAppear setTimeout ${this.duration} ${this.screenWidth}`) 202 animateTo({ duration: this.duration, curve: Curve.Linear, onFinish: () => { 203 this.add(this.deviceId , `${fp2px(this.screenWidth)} * ${this.screenHeight}`) 204 } }, () => { 205 Logger.info(TAG, 'setTimeout translates') 206 this.imageTranslate = this.screenWidth 207 Logger.info(TAG, `setTimeout translates = ${this.imageTranslate}`) 208 }) 209 } 210 Logger.info(TAG, 'aboutToAppear end') 211 } 212 213 async onInit() { 214 await this.setFullScreen() 215 distributedDataModel.onChangeCallback(this.dataChangeCallback) 216 distributedDataModel.onStatusCallback((sessionId, networkId, status) => { 217 Logger.info(TAG, `onStatusCallback ${sessionId} ${networkId} ${status}`) 218 if (status === 'online') { 219 prompt.showToast({ message: `${networkId}${this.onlineText}` }) 220 } else if (status === 'offline') { 221 prompt.showToast({ message: `${networkId}${this.offlineText}` }) 222 } 223 }) 224 } 225 226 aboutToDisappear() { 227 distributedDataModel.clearCallback() 228 this.deviceTag = 0 229 this.countCallBack = 0 230 } 231 232 /** 233 * 分布式对象添加数据 234 * 235 * @param deviceId 设备id 236 * @param screenSize 本机屏幕大小 237 */ 238 async add(deviceId: string, screenSize: string) { 239 Logger.info(TAG, `add start`) 240 distributedDataModel.add(deviceId, screenSize, await this.convertResourceToString($r('app.string.already_complete'))) 241 } 242 243 244 /** 245 * 设置全屏,屏幕长亮 246 */ 247 async setFullScreen() { 248 Logger.info(TAG, `setFullScreen start`) 249 try { 250 let defaultDisplay = await display.getDefaultDisplay() 251 Logger.info(TAG, `setFullScreen densityDPI = ${defaultDisplay.densityDPI}`) 252 this.screenWidth = px2fp(defaultDisplay.width) 253 this.screenHeight = defaultDisplay.height 254 this.duration = this.screenWidth / dmsConst.PLAY_SPEED * dmsConst.CONVERT_MILLISECOND // 匀速播放时长 255 Logger.info(TAG, `setFullScreen width = ${this.width}`) 256 const topWindow = await window.getTopWindow() 257 await topWindow.setFullScreen(true) 258 await topWindow.setKeepScreenOn(true) 259 } catch (err) { 260 Logger.error(TAG, `setFullScreen fail , code = ${err.code}`) 261 } 262 } 263 264 /** 265 * 注册设备 266 */ 267 registerDevice() { 268 Logger.info(TAG, `registerDevice startAbility devices = ${JSON.stringify(this.devices)}`) 269 if (this.status.length > this.deviceTag) { 270 this.status[this.deviceTag] = true 271 } 272 if (this.devices.length > this.deviceTag + dmsConst.ONE) { 273 this.startAbility(this.devices[++this.deviceTag].deviceId) 274 } 275 Logger.info(TAG, 'registerDevice startAbility end') 276 } 277 278 /** 279 * 启动远程设备 280 * 281 * @param deviceId 设备id 282 */ 283 async startAbility(deviceId) { 284 Logger.info(TAG, `startAbility deviceId: ${deviceId}`) 285 let context = getContext(this) as any 286 await context.startAbility({ 287 bundleName: dmsConst.BUNDLE_NAME, 288 abilityName: dmsConst.ABILITY_NAME, 289 deviceId: deviceId, 290 parameters: { 291 isFA: 'isFA' 292 } 293 }).then((data) => { 294 Logger.info(TAG, `start ability finished data = ${JSON.stringify(data)}`) 295 }) 296 } 297}