• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2025-2025 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 UIExtensionContentSession from '@ohos.app.ability.UIExtensionContentSession';
17import opp from '@ohos.bluetooth.opp';
18import common from '@ohos.app.ability.common';
19import fs from '@ohos.file.fs';
20
21export const CLOSE = 1;
22
23export const BACK = 0;
24
25const TAG: string = 'BluetoothShare: ';
26const BUNDLE_NAME: string = 'com.huawei.hmos.settings';
27const ABILITY_NAME: string = 'BluetoothOppServiceUIExtensionAbility';
28
29@Entry
30@Component
31export struct BtServicesComponent {
32  uiExtensionProxy?: UIExtensionProxy;
33  private serverMac: string = '';
34  private fileHolders: Array<opp.FileHolder> = [];
35
36  build() {
37    Column() {
38      UIExtensionComponent({
39        bundleName: BUNDLE_NAME,
40        abilityName: ABILITY_NAME,
41        parameters: {
42          'ability.want.params.uiExtensionType': 'sys/commonUI',
43        }
44      })
45        .backgroundColor('#01111111')
46        .onRemoteReady((proxy) => {
47          console.log(TAG, 'onRemoteReady.');
48          this.uiExtensionProxy = proxy;
49        })
50        .onError((error) => {
51          console.log(TAG, `onError code: ${error?.code} message: ${error?.message}`);
52        })
53        .onTerminated(() => {
54        })
55        .onReceive((data: Record<string, string | Object>) => {
56          console.log(TAG, 'onReceive: ' + data?.action);
57          if (!data) {
58            console.error(TAG, 'onReceive error');
59            return;
60          }
61          this.dealReceivedData(data);
62        })
63        .size({ width: '100%', height: '100%'})
64        .expandSafeArea([SafeAreaType.SYSTEM], [SafeAreaEdge.BOTTOM, SafeAreaEdge.TOP])
65    }
66  }
67
68  /**
69   * 关闭、退出蓝牙分享页面
70   */
71  private closeSheetPage(session: UIExtensionContentSession, code: number, message?: string) {
72    if (!session) {
73      console.log(TAG, `invalid session`);
74      return;
75    }
76    console.log(TAG, `closeSheetPage start`);
77    let result: common.AbilityResult = {
78      resultCode: code
79    };
80    if (message) {
81      result.want = {
82        parameters: {
83          message: message
84        }
85      }
86    }
87    try {
88      session?.terminateSelfWithResult(result).then(() => {
89        console.log(TAG, `terminateSelfWithResult success`);
90      }).catch((error: Error) => {
91        console.log(TAG, `terminateSelfWithResult failed, err name: ${error?.name}`);
92      });
93    } catch (err) {
94      console.log(TAG, `closeSheetPage error, msg: ${err.message}`);
95    }
96  }
97
98  aboutToAppear(): void {
99    console.log(TAG, 'aboutToAppear.');
100  }
101
102  aboutToDisappear(): void {
103    console.log(TAG, 'aboutToDisappear.');
104  }
105
106  private async dealReceivedData(data: Record<string, Object>): Promise<void> {
107    const session: UIExtensionContentSession | undefined = LocalStorage.getShared()?.get<UIExtensionContentSession>('session');
108    if (session === undefined) {
109      console.log(TAG, 'cannot get session.');
110      return;
111    }
112    if (data['action'] === 'sendDeviceInfo') {
113      console.log(TAG, 'sendDeviceInfo message.');
114      let serverMac: string = data['deviceInfo'] as string;
115      this.serverMac = serverMac;
116      this.sendData();
117    }
118    if (data['action'] === 'closeSheet') {
119      console.log(TAG, 'closeSheet message.');
120      this.closeSheetPage(session, CLOSE);
121    }
122    if (data['action'] === 'backSheet') {
123      console.log(TAG, 'backSheet message.');
124      this.closeSheetPage(session, BACK);
125    }
126  }
127
128  private async sendData(): Promise<void> {
129    console.log(`${TAG} sendData is called.`);
130    let fileUris = AppStorage.Get('sendFileUris');
131    let length = AppStorage.Get('sendFileUrisLength');
132    try {
133      let oppProfile = opp.createOppServerProfile();
134      for (let i = 0; i < length; i++) {
135        let filePath = decodeURIComponent(fileUris[i]);
136        let file = fs.openSync(filePath, fs.OpenMode.READ_ONLY);
137        console.log(`${TAG} deal file:` + file.fd);
138        let stat: fs.Stat = fs.statSync(file.fd);
139        let fileHolder: opp.FileHolder = {
140          filePath: filePath,
141          fileSize: stat.size,
142          fileFd: file.fd
143        };
144        this.fileHolders.push(fileHolder);
145        console.log(`${TAG} fileHolder info: ` + JSON.stringify(fileHolder));
146      }
147      await oppProfile.sendFile(this.serverMac, this.fileHolders);
148      const session: UIExtensionContentSession | undefined =
149        LocalStorage.getShared()?.get<UIExtensionContentSession>('session');
150      for (let i = 0; i < this.fileHolders.length; i++) {
151        console.log(TAG, 'close fileHolders fd.');
152        if (this.fileHolders[i].fileFd != -1) {
153          fs.close(this.fileHolders[i].fileFd);
154          this.fileHolders[i].fileFd = -1;
155        }
156      }
157      if (session === undefined) {
158        console.log(TAG, 'cannot get session.');
159        return;
160      }
161      this.closeSheetPage(session, CLOSE);
162    } catch (err) {
163      console.error(`${TAG} sendData err`);
164    }
165  }
166}