• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 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 */
15import rpc from '@ohos.rpc';
16import ServiceExtensionAbility from '@ohos.app.ability.ServiceExtensionAbility';
17import Logger from '../model/Logger';
18import {
19  APPLICATION_BUNDLE_NAME,
20  APPLICATION_ABILITY_NAME,
21  APPLICATION_SERVICE_NAME,
22  MusicSharedEventCode,
23  MusicConnectEvent
24} from '../common/MusicSharedDefinition';
25
26const TAG: string = 'ServiceAbility'
27const CONNECT_REMOTE_TIMEOUT = 10000
28
29let remoteProxy: rpc.RemoteProxy = null;
30
31class DistributedMusicServiceExtension extends rpc.RemoteObject {
32  private context
33
34  constructor(des, context) {
35    super(des)
36    this.context = context
37  }
38
39  startServiceAbility(want): void {
40    try {
41      let connectOptions = {
42        onConnect(elementName, remote): void {
43          Logger.info(TAG, `Start remote service has been succeeded, elementName= ${JSON.stringify(elementName)}, remote= ${JSON.stringify(remote)}`)
44          if (remote === null) {
45            Logger.info(TAG, 'Remote is null')
46          }
47          remoteProxy = remote as rpc.RemoteProxy;
48          clearTimeout(timeoutId)
49          let remoteServiceExtensionConnectEvent = AppStorage.Get<(event: string) => void>('remoteServiceExtensionConnectEvent');
50          if (remoteServiceExtensionConnectEvent === undefined) {
51            Logger.info(TAG, `Connect remote service callback is ${JSON.stringify(remoteServiceExtensionConnectEvent)}`);
52            return;
53          }
54          remoteServiceExtensionConnectEvent(MusicConnectEvent.EVENT_CONNECT);
55        },
56        onDisconnect(elementName): void {
57          Logger.info(TAG, `ServiceExtension has onDisconnected,elementName= ${JSON.stringify(elementName)}`)
58          clearTimeout(timeoutId)
59          remoteProxy = null;
60          let remoteServiceExtensionConnectEvent = AppStorage.Get<(event: string) => void>('remoteServiceExtensionConnectEvent');
61          if (remoteServiceExtensionConnectEvent === undefined) {
62            Logger.info(TAG, `Disconnect remote service callback is ${JSON.stringify(remoteServiceExtensionConnectEvent)}`);
63            return;
64          }
65          remoteServiceExtensionConnectEvent(MusicConnectEvent.EVENT_DISCONNECT);
66        },
67        onFailed(code): void {
68          Logger.info(TAG, `ServiceExtension has onFailed, code= ${JSON.stringify(code)}`)
69          clearTimeout(timeoutId)
70          remoteProxy = null;
71          let remoteServiceExtensionConnectEvent = AppStorage.Get<(event: string) => void>('remoteServiceExtensionConnectEvent');
72          if (remoteServiceExtensionConnectEvent === undefined) {
73            Logger.info(TAG, `Failed remote service callback is ${JSON.stringify(remoteServiceExtensionConnectEvent)}`);
74            return;
75          }
76          remoteServiceExtensionConnectEvent(MusicConnectEvent.EVENT_FAILED);
77        }
78      }
79
80      this.context.connectServiceExtensionAbility(want, connectOptions)
81      let timeoutId = setTimeout(() => {
82        Logger.info(TAG, 'Connect remote service extension timeout')
83        let remoteServiceExtensionConnectEvent = AppStorage.Get<(event: string) => void>('remoteServiceExtensionConnectEvent');
84        if (remoteServiceExtensionConnectEvent === undefined) {
85          Logger.info(TAG, `Timeout remote service callback is ${JSON.stringify(remoteServiceExtensionConnectEvent)}`);
86          return;
87        }
88        remoteServiceExtensionConnectEvent(MusicConnectEvent.EVENT_TIMEOUT);
89      }, CONNECT_REMOTE_TIMEOUT)
90    } catch (err) {
91      Logger.info(TAG, `ConnectServiceExtensionAbility has failed, want= ${JSON.stringify(want)}, err= ${JSON.stringify(err)}`)
92    }
93  }
94
95  stopServiceAbility(want): void {
96    this.context.stopServiceExtensionAbility(want).then(() => {
97      Logger.info(TAG, `Stop service has been succeeded, want= ${JSON.stringify(want)}`)
98    }).catch((err) => {
99      Logger.info(TAG, `Stop service has been failed, want= ${JSON.stringify(want)}, err= ${JSON.stringify(err)}`)
100    })
101  }
102
103  onRemoteRequest(code: number, data: rpc.MessageParcel, reply: rpc.MessageParcel, options: rpc.MessageOption): boolean {
104    if (code === MusicSharedEventCode.START_DISTRIBUTED_MUSIC_SERVICE) {
105      let deviceId = data.readString()
106      let stringJson: string = data.readString()
107      let jsonData = JSON.parse(stringJson)
108      let params = {
109        uri: jsonData.uri,
110        seekTo: jsonData.seekTo,
111        isPlaying: jsonData.isPlaying,
112        flag: 'START_REMOTE_DISTRIBUTED_MUSIC_SERVICE'
113      }
114      let want = {
115        deviceId: deviceId,
116        bundleName: APPLICATION_BUNDLE_NAME,
117        abilityName: APPLICATION_SERVICE_NAME,
118        parameters: params
119      }
120      this.startServiceAbility(want)
121    } else if (code === MusicSharedEventCode.STOP_DISTRIBUTED_MUSIC_SERVICE) {
122      let deviceId = data.readString()
123      let want = {
124        deviceId: deviceId,
125        bundleName: APPLICATION_BUNDLE_NAME,
126        abilityName: APPLICATION_SERVICE_NAME
127      }
128      this.stopServiceAbility(want)
129    } else if (code === MusicSharedEventCode.PLAY_MUSIC_SERVICE) {
130      if (remoteProxy === null) {
131        Logger.info(TAG, 'Play local is null')
132        return false
133      }
134      let option = new rpc.MessageOption()
135      let data = new rpc.MessageParcel()
136      let reply = new rpc.MessageParcel()
137      remoteProxy.sendRequest(MusicSharedEventCode.PLAY_MUSIC_SERVICE_REMOTE, data, reply, option);
138    } else if (code === MusicSharedEventCode.PAUSE_MUSIC_SERVICE) {
139      if (remoteProxy === null) {
140        Logger.info(TAG, 'Pause local is null')
141        return false
142      }
143      let option = new rpc.MessageOption()
144      let data = new rpc.MessageParcel()
145      let reply = new rpc.MessageParcel()
146      remoteProxy.sendRequest(MusicSharedEventCode.PAUSE_MUSIC_SERVICE_REMOTE, data, reply, option);
147    } else if (code === MusicSharedEventCode.PLAY_MUSIC_SERVICE_REMOTE) {
148      let musicPlay = AppStorage.Get<() => void>('musicPlay');
149      if (musicPlay === undefined) {
150        Logger.error(TAG, 'get play callback form app storage falied');
151        return false;
152      }
153      musicPlay();
154    } else if (code === MusicSharedEventCode.PAUSE_MUSIC_SERVICE_REMOTE) {
155      let musicPause = AppStorage.Get<() => void>('musicPause');
156      if (musicPause === undefined) {
157        Logger.error(TAG, 'get pause callback form app storage falied');
158        return false;
159      }
160      musicPause();
161    } else if (code === MusicSharedEventCode.STOP_LOCAL_SERIVCE) {
162      this.context.terminateSelf().then(() => {
163        Logger.info(TAG, 'TerminateSelf service extension has been succeeded')
164      }).catch((err) => {
165        Logger.info(TAG, `TerminateSelf service extension has been failed err= ${JSON.stringify(err)}`)
166      })
167    } else {
168      Logger.info(TAG, 'Invalid instruction')
169      return false
170    }
171    return true
172  }
173}
174
175export default class ServiceAbility extends ServiceExtensionAbility {
176  onCreate(want): void {
177    if (want.parameters.flag === 'START_REMOTE_DISTRIBUTED_MUSIC_SERVICE') {
178      let localwant = {
179        bundleName: APPLICATION_BUNDLE_NAME,
180        abilityName: APPLICATION_ABILITY_NAME,
181        parameters: want.parameters
182      }
183      this.context.startAbility(localwant).then(() => {
184        Logger.info(TAG, 'StartUIAbility has been succeeded')
185      }).catch((err) => {
186        Logger.info(TAG, `StartUIAbility has been failed, err= ${JSON.stringify(err)}`)
187      })
188    }
189  }
190
191  onDestroy(): void {
192    Logger.info(TAG, 'ServiceAbility onDestroy')
193  }
194
195  onRequest(want, startId): void {
196    Logger.info(TAG, 'ServiceAbility onRequest')
197  }
198
199  onConnect(want): rpc.RemoteObject {
200    Logger.info(TAG, 'ServiceAbility onConnect')
201    return new DistributedMusicServiceExtension('ohos.samples.distributedMusicServiceExtension', this.context)
202  }
203
204  onDisconnect(want): void {
205    Logger.info(TAG, 'ServiceAbility onDisconnect')
206  }
207
208  onReconnect(want): void {
209    Logger.info(TAG, 'ServiceAbility onReconnect')
210  }
211
212  onConfigurationUpdate(newConfig): void {
213    Logger.info(TAG, 'ServiceAbility onConfigurationUpdate')
214  }
215
216  onDump(params: Array<string>): Array<string> {
217    Logger.info(TAG, 'ServiceAbility onDump')
218    return params
219  }
220}