1 /*
2  * Copyright (C) 2021-2024 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 
16 #include "player_server_state.h"
17 #include "media_errors.h"
18 #include "media_log.h"
19 #include "media_dfx.h"
20 #include "account_subscriber.h"
21 #include "os_account_manager.h"
22 #include "plugin/plugin_time.h"
23 
24 namespace {
25 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, LOG_DOMAIN_PLAYER, "PlayerServerState"};
26 constexpr int32_t COMPLETED_PLAY_REPORT_MS = 3000;
27 }
28 
29 namespace OHOS {
30 namespace Media {
ReportInvalidOperation() const31 void PlayerServer::BaseState::ReportInvalidOperation() const
32 {
33     MEDIA_LOGE("invalid operation for %{public}s", GetStateName().c_str());
34     (void)server_.taskMgr_.MarkTaskDone("ReportInvalidOperation");
35 }
36 
Prepare()37 int32_t PlayerServer::BaseState::Prepare()
38 {
39     ReportInvalidOperation();
40     return MSERR_INVALID_STATE;
41 }
42 
Play()43 int32_t PlayerServer::BaseState::Play()
44 {
45     ReportInvalidOperation();
46     return MSERR_INVALID_STATE;
47 }
48 
Pause(bool isSystemOperation)49 int32_t PlayerServer::BaseState::Pause(bool isSystemOperation)
50 {
51     (void)isSystemOperation;
52     ReportInvalidOperation();
53     return MSERR_INVALID_STATE;
54 }
55 
PauseDemuxer()56 int32_t PlayerServer::BaseState::PauseDemuxer()
57 {
58     ReportInvalidOperation();
59     return MSERR_INVALID_STATE;
60 }
61 
ResumeDemuxer()62 int32_t PlayerServer::BaseState::ResumeDemuxer()
63 {
64     ReportInvalidOperation();
65     return MSERR_INVALID_STATE;
66 }
67 
Seek(int32_t mSeconds,PlayerSeekMode mode)68 int32_t PlayerServer::BaseState::Seek(int32_t mSeconds, PlayerSeekMode mode)
69 {
70     (void)mSeconds;
71     (void)mode;
72 
73     ReportInvalidOperation();
74     return MSERR_INVALID_STATE;
75 }
76 
Stop()77 int32_t PlayerServer::BaseState::Stop()
78 {
79     ReportInvalidOperation();
80     return MSERR_INVALID_STATE;
81 }
82 
SetPlaybackSpeed(PlaybackRateMode mode)83 int32_t PlayerServer::BaseState::SetPlaybackSpeed(PlaybackRateMode mode)
84 {
85     (void)mode;
86 
87     ReportInvalidOperation();
88     return MSERR_INVALID_STATE;
89 }
90 
SeekContinous(int32_t mSeconds,int64_t batchNo)91 int32_t PlayerServer::BaseState::SeekContinous(int32_t mSeconds, int64_t batchNo)
92 {
93     (void)mSeconds;
94     (void)batchNo;
95 
96     ReportInvalidOperation();
97     return MSERR_INVALID_STATE;
98 }
99 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)100 int32_t PlayerServer::BaseState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
101 {
102     (void)start;
103     (void)end;
104     (void)mode;
105 
106     ReportInvalidOperation();
107     return MSERR_INVALID_STATE;
108 }
109 
MessageSeekDone(int32_t extra)110 int32_t PlayerServer::BaseState::MessageSeekDone(int32_t extra)
111 {
112     int32_t ret = MSERR_OK;
113     (void)server_.taskMgr_.MarkTaskDone("seek done");
114     MediaTrace::TraceEnd("PlayerServer::Seek", FAKE_POINTER(&server_));
115     MediaTrace::TraceEnd("PlayerServer::track", FAKE_POINTER(&server_));
116     if (server_.disableNextSeekDone_ && extra == 0) {
117         ret = MSERR_UNSUPPORT;
118     }
119     server_.disableNextSeekDone_ = false;
120     return ret;
121 }
122 
MessageTrackDone(int32_t extra)123 int32_t PlayerServer::BaseState::MessageTrackDone(int32_t extra)
124 {
125     (void)extra;
126     (void)server_.taskMgr_.MarkTaskDone("track done");
127     MediaTrace::TraceEnd("PlayerServer::track", FAKE_POINTER(&server_));
128     return MSERR_OK;
129 }
130 
MessageTrackInfoUpdate()131 int32_t PlayerServer::BaseState::MessageTrackInfoUpdate()
132 {
133     (void)server_.taskMgr_.MarkTaskDone("addsubtitle done");
134     MediaTrace::TraceEnd("PlayerServer::AddSubSource", FAKE_POINTER(&server_));
135     return MSERR_OK;
136 }
137 
MessageSpeedDone()138 int32_t PlayerServer::BaseState::MessageSpeedDone()
139 {
140     (void)server_.taskMgr_.MarkTaskDone("speed done");
141     MediaTrace::TraceEnd("PlayerServer::SetPlaybackSpeed", FAKE_POINTER(&server_));
142     return MSERR_OK;
143 }
144 
MessageStateChange(int32_t extra)145 int32_t PlayerServer::BaseState::MessageStateChange(int32_t extra)
146 {
147     if (extra == PLAYER_PLAYBACK_COMPLETE) {
148         HandlePlaybackComplete(extra);
149     } else {
150         HandleStateChange(extra);
151         MEDIA_LOGI("0x%{public}06" PRIXPTR " Callback State change, currentState is %{public}s",
152             FAKE_POINTER(this), server_.GetStatusDescription(extra).c_str());
153     }
154 
155     if (extra == PLAYER_STOPPED && server_.disableStoppedCb_) {
156         MEDIA_LOGI("0x%{public}06" PRIXPTR " Callback State change disable StoppedCb", FAKE_POINTER(this));
157         server_.disableStoppedCb_ = false;
158         return MSERR_UNSUPPORT;
159     }
160     return MSERR_OK;
161 }
162 
OnMessageReceived(PlayerOnInfoType type,int32_t extra,const Format & infoBody)163 int32_t PlayerServer::BaseState::OnMessageReceived(PlayerOnInfoType type, int32_t extra, const Format &infoBody)
164 {
165     MEDIA_LOGD("message received, type = %{public}d, extra = %{public}d", type, extra);
166     (void)infoBody;
167 
168     int32_t ret = MSERR_OK;
169     switch (type) {
170         case INFO_TYPE_SEEKDONE:
171             ret = MessageSeekDone(extra);
172             break;
173 
174         case INFO_TYPE_SPEEDDONE:
175             ret = MessageSpeedDone();
176             break;
177 
178         case INFO_TYPE_EOS:
179             HandleEos();
180             break;
181 
182         case INFO_TYPE_STATE_CHANGE:
183             ret = MessageStateChange(extra);
184             break;
185 
186         case INFO_TYPE_TRACK_DONE:
187             ret = MessageTrackDone(extra);
188             break;
189 
190         case INFO_TYPE_ADD_SUBTITLE_DONE:
191             ret = MessageTrackInfoUpdate();
192             break;
193 
194         case INFO_TYPE_TRACK_INFO_UPDATE:
195             ret = MessageTrackInfoUpdate();
196             break;
197         case INFO_TYPE_INTERRUPT_EVENT:
198             HandleInterruptEvent(infoBody);
199             break;
200 
201         case INFO_TYPE_AUDIO_DEVICE_CHANGE:
202             HandleAudioDeviceChangeEvent(infoBody);
203             break;
204 
205         default:
206             break;
207     }
208 
209     return ret;
210 }
211 
StateEnter()212 void PlayerServer::IdleState::StateEnter()
213 {
214     (void)server_.HandleReset();
215 }
216 
Prepare()217 int32_t PlayerServer::InitializedState::Prepare()
218 {
219     server_.ChangeState(server_.preparingState_);
220     return MSERR_OK;
221 }
222 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)223 int32_t PlayerServer::InitializedState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
224 {
225     return server_.HandleSetPlayRange(start, end, mode);
226 }
227 
StateEnter()228 void PlayerServer::PreparingState::StateEnter()
229 {
230     (void)server_.HandlePrepare();
231     MEDIA_LOGD("PlayerServer::PreparingState::StateEnter finished");
232 }
233 
Stop()234 int32_t PlayerServer::PreparingState::Stop()
235 {
236     (void)server_.HandleStop();
237     server_.ChangeState(server_.stoppedState_);
238     return MSERR_OK;
239 }
240 
HandleStateChange(int32_t newState)241 void PlayerServer::PreparingState::HandleStateChange(int32_t newState)
242 {
243     if (newState == PLAYER_PREPARED || newState == PLAYER_STATE_ERROR) {
244         MediaTrace::TraceEnd("PlayerServer::PrepareAsync", FAKE_POINTER(&server_));
245         if (newState == PLAYER_STATE_ERROR) {
246             server_.lastOpStatus_ = PLAYER_STATE_ERROR;
247             server_.ChangeState(server_.initializedState_);
248         } else {
249             server_.ChangeState(server_.preparedState_);
250         }
251         (void)server_.taskMgr_.MarkTaskDone("preparing->prepared done");
252     }
253 }
254 
Prepare()255 int32_t PlayerServer::PreparedState::Prepare()
256 {
257     (void)server_.taskMgr_.MarkTaskDone("double prepare");
258     return MSERR_OK;
259 }
260 
Play()261 int32_t PlayerServer::PreparedState::Play()
262 {
263     return server_.HandlePlay();
264 }
265 
Seek(int32_t mSeconds,PlayerSeekMode mode)266 int32_t PlayerServer::PreparedState::Seek(int32_t mSeconds, PlayerSeekMode mode)
267 {
268     return server_.HandleSeek(mSeconds, mode);
269 }
270 
Stop()271 int32_t PlayerServer::PreparedState::Stop()
272 {
273     return server_.HandleStop();
274 }
275 
SetPlaybackSpeed(PlaybackRateMode mode)276 int32_t PlayerServer::PreparedState::SetPlaybackSpeed(PlaybackRateMode mode)
277 {
278     return server_.HandleSetPlaybackSpeed(mode);
279 }
280 
SeekContinous(int32_t mSeconds,int64_t batchNo)281 int32_t PlayerServer::PreparedState::SeekContinous(int32_t mSeconds, int64_t batchNo)
282 {
283     return server_.HandleSeekContinous(mSeconds, batchNo);
284 }
285 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)286 int32_t PlayerServer::PreparedState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
287 {
288     return server_.HandleSetPlayRange(start, end, mode);
289 }
290 
HandleStateChange(int32_t newState)291 void PlayerServer::PreparedState::HandleStateChange(int32_t newState)
292 {
293     if (newState == PLAYER_STARTED) {
294         MediaTrace::TraceEnd("PlayerServer::Play", FAKE_POINTER(&server_));
295         server_.ChangeState(server_.playingState_);
296         (void)server_.taskMgr_.MarkTaskDone("prepared->started done");
297     } else if (newState == PLAYER_STOPPED) {
298         MediaTrace::TraceEnd("PlayerServer::Stop", FAKE_POINTER(&server_));
299         server_.ChangeState(server_.stoppedState_);
300         (void)server_.taskMgr_.MarkTaskDone("prepared->stopped done");
301     } else if (newState == PLAYER_STATE_ERROR) {
302         server_.lastOpStatus_ = PLAYER_STATE_ERROR;
303         server_.ChangeState(server_.initializedState_);
304         (void)server_.taskMgr_.MarkTaskDone("prepared->error done");
305     }
306 }
307 
HandleEos()308 void PlayerServer::PreparedState::HandleEos()
309 {
310     server_.PreparedHandleEos();
311 }
312 
Play()313 int32_t PlayerServer::PlayingState::Play()
314 {
315     (void)server_.taskMgr_.MarkTaskDone("double play");
316     return MSERR_OK;
317 }
318 
Pause(bool isSystemOperation)319 int32_t PlayerServer::PlayingState::Pause(bool isSystemOperation)
320 {
321     return server_.HandlePause(isSystemOperation);
322 }
323 
PauseDemuxer()324 int32_t PlayerServer::PlayingState::PauseDemuxer()
325 {
326     return server_.HandlePauseDemuxer();
327 }
328 
ResumeDemuxer()329 int32_t PlayerServer::PlayingState::ResumeDemuxer()
330 {
331     return server_.HandleResumeDemuxer();
332 }
333 
Seek(int32_t mSeconds,PlayerSeekMode mode)334 int32_t PlayerServer::PlayingState::Seek(int32_t mSeconds, PlayerSeekMode mode)
335 {
336     return server_.HandleSeek(mSeconds, mode);
337 }
338 
Stop()339 int32_t PlayerServer::PlayingState::Stop()
340 {
341     return server_.HandleStop();
342 }
343 
SetPlaybackSpeed(PlaybackRateMode mode)344 int32_t PlayerServer::PlayingState::SetPlaybackSpeed(PlaybackRateMode mode)
345 {
346     return server_.HandleSetPlaybackSpeed(mode);
347 }
348 
SeekContinous(int32_t mSeconds,int64_t batchNo)349 int32_t PlayerServer::PlayingState::SeekContinous(int32_t mSeconds, int64_t batchNo)
350 {
351     MEDIA_LOGE("not supported SeekContinous in PlayingState, please pause in player server");
352     (void)mSeconds;
353     (void)batchNo;
354     ReportInvalidOperation();
355     return MSERR_INVALID_STATE;
356 }
357 
HandleStateChange(int32_t newState)358 void PlayerServer::PlayingState::HandleStateChange(int32_t newState)
359 {
360     if (newState == PLAYER_PAUSED) {
361         MediaTrace::TraceEnd("PlayerServer::Pause", FAKE_POINTER(&server_));
362         server_.ChangeState(server_.pausedState_);
363         (void)server_.taskMgr_.MarkTaskDone("started->paused done");
364     } else if (newState == PLAYER_STOPPED) {
365         MediaTrace::TraceEnd("PlayerServer::Stop", FAKE_POINTER(&server_));
366         server_.ChangeState(server_.stoppedState_);
367         (void)server_.taskMgr_.MarkTaskDone("started->stopped done");
368     }
369 }
370 
HandlePlaybackComplete(int32_t extra)371 void PlayerServer::PlayingState::HandlePlaybackComplete(int32_t extra)
372 {
373     (void)extra;
374     server_.lastOpStatus_ = PLAYER_PLAYBACK_COMPLETE;
375     server_.ChangeState(server_.playbackCompletedState_);
376     (void)server_.taskMgr_.MarkTaskDone("playing->completed done");
377 }
378 
HandleEos()379 void PlayerServer::PlayingState::HandleEos()
380 {
381     server_.HandleEos();
382 }
383 
HandleInterruptEvent(const Format & infoBody)384 void PlayerServer::PlayingState::HandleInterruptEvent(const Format &infoBody)
385 {
386     server_.HandleInterruptEvent(infoBody);
387 }
388 
HandleAudioDeviceChangeEvent(const Format & infoBody)389 void PlayerServer::PlayingState::HandleAudioDeviceChangeEvent(const Format &infoBody)
390 {
391     (void) infoBody;
392 }
393 
StateEnter()394 void PlayerServer::PlayingState::StateEnter()
395 {
396     int32_t userId = server_.GetUserId();
397     bool isBootCompleted = server_.IsBootCompleted();
398     if (userId <= 0 || !isBootCompleted) {
399         MEDIA_LOGI("PlayingState::StateEnter userId = %{public}d, isBootCompleted = %{public}d, return",
400             userId, isBootCompleted);
401         return;
402     }
403 
404     bool isForeground = true;
405     AccountSA::OsAccountManager::IsOsAccountForeground(userId, isForeground);
406     MEDIA_LOGI("PlayingState::StateEnter userId = %{public}d isForeground = %{public}d isBootCompleted = %{public}d",
407         userId, isForeground, isBootCompleted);
408     if (!isForeground && !server_.GetInterruptState()) {
409         server_.OnSystemOperation(
410             PlayerOnSystemOperationType::OPERATION_TYPE_PAUSE, PlayerOperationReason::OPERATION_REASON_USER_BACKGROUND);
411         return;
412     }
413     std::shared_ptr<CommonEventReceiver> receiver = server_.GetCommonEventReceiver();
414     AccountSubscriber::GetInstance()->RegisterCommonEventReceiver(userId, receiver);
415 }
416 
StateExit()417 void PlayerServer::PlayingState::StateExit()
418 {
419     std::shared_ptr<CommonEventReceiver> receiver = server_.GetCommonEventReceiver();
420     AccountSubscriber::GetInstance()->UnregisterCommonEventReceiver(server_.GetUserId(), receiver);
421 }
422 
Play()423 int32_t PlayerServer::PausedState::Play()
424 {
425     return server_.HandlePlay();
426 }
427 
Pause(bool isSystemOperation)428 int32_t PlayerServer::PausedState::Pause(bool isSystemOperation)
429 {
430     (void)server_.taskMgr_.MarkTaskDone("double pause");
431     return MSERR_OK;
432 }
433 
Seek(int32_t mSeconds,PlayerSeekMode mode)434 int32_t PlayerServer::PausedState::Seek(int32_t mSeconds, PlayerSeekMode mode)
435 {
436     return server_.HandleSeek(mSeconds, mode);
437 }
438 
Stop()439 int32_t PlayerServer::PausedState::Stop()
440 {
441     return server_.HandleStop();
442 }
443 
SetPlaybackSpeed(PlaybackRateMode mode)444 int32_t PlayerServer::PausedState::SetPlaybackSpeed(PlaybackRateMode mode)
445 {
446     return server_.HandleSetPlaybackSpeed(mode);
447 }
448 
SeekContinous(int32_t mSeconds,int64_t batchNo)449 int32_t PlayerServer::PausedState::SeekContinous(int32_t mSeconds, int64_t batchNo)
450 {
451     return server_.HandleSeekContinous(mSeconds, batchNo);
452 }
453 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)454 int32_t PlayerServer::PausedState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
455 {
456     return server_.HandleSetPlayRange(start, end, mode);
457 }
458 
HandleStateChange(int32_t newState)459 void PlayerServer::PausedState::HandleStateChange(int32_t newState)
460 {
461     if (newState == PLAYER_STARTED) {
462         MediaTrace::TraceEnd("PlayerServer::Play", FAKE_POINTER(&server_));
463         server_.ChangeState(server_.playingState_);
464         (void)server_.taskMgr_.MarkTaskDone("paused->started done");
465     } else if (newState == PLAYER_STOPPED) {
466         MediaTrace::TraceEnd("PlayerServer::Stop", FAKE_POINTER(&server_));
467         server_.ChangeState(server_.stoppedState_);
468         (void)server_.taskMgr_.MarkTaskDone("paused->stopped done");
469     }
470 }
471 
HandleEos()472 void PlayerServer::PausedState::HandleEos()
473 {
474     server_.HandleEos();
475 }
476 
Prepare()477 int32_t PlayerServer::StoppedState::Prepare()
478 {
479     server_.ChangeState(server_.preparingState_);
480     return MSERR_OK;
481 }
482 
Stop()483 int32_t PlayerServer::StoppedState::Stop()
484 {
485     (void)server_.taskMgr_.MarkTaskDone("double stop");
486     return MSERR_OK;
487 }
488 
HandleStateChange(int32_t newState)489 void PlayerServer::StoppedState::HandleStateChange(int32_t newState)
490 {
491     if (newState == PLAYER_STATE_ERROR) {
492         (void)server_.taskMgr_.MarkTaskDone("stopped->error done");
493     } else if (newState == PLAYER_STOPPED) {
494         (void)server_.taskMgr_.MarkTaskDone("double stop");
495     }
496 }
497 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)498 int32_t PlayerServer::StoppedState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
499 {
500     return server_.HandleSetPlayRange(start, end, mode);
501 }
502 
StateEnter()503 void PlayerServer::PlaybackCompletedState::StateEnter()
504 {
505     MEDIA_LOGD("state enter completed");
506     stateEnterTimeMs_ = Plugins::GetCurrentMillisecond();
507 }
508 
Play()509 int32_t PlayerServer::PlaybackCompletedState::Play()
510 {
511     auto res = server_.HandlePlay();
512     auto timeNow = Plugins::GetCurrentMillisecond();
513     auto timeDiff = timeNow - stateEnterTimeMs_;
514     MEDIA_LOGD("timeNow %{public}" PRId64 " timeStart %{public}" PRId64 " timeDiff %{public}" PRId64,
515         timeNow, stateEnterTimeMs_, timeDiff);
516     CHECK_AND_RETURN_RET(timeDiff < COMPLETED_PLAY_REPORT_MS, res);
517     server_.HandleEosPlay();
518     return res;
519 }
520 
Seek(int32_t mSeconds,PlayerSeekMode mode)521 int32_t PlayerServer::PlaybackCompletedState::Seek(int32_t mSeconds, PlayerSeekMode mode)
522 {
523     return server_.HandleSeek(mSeconds, mode);
524 }
525 
SeekContinous(int32_t mSeconds,int64_t batchNo)526 int32_t PlayerServer::PlaybackCompletedState::SeekContinous(int32_t mSeconds, int64_t batchNo)
527 {
528     return server_.HandleSeekContinous(mSeconds, batchNo);
529 }
530 
SetPlayRangeWithMode(int64_t start,int64_t end,PlayerSeekMode mode)531 int32_t PlayerServer::PlaybackCompletedState::SetPlayRangeWithMode(int64_t start, int64_t end, PlayerSeekMode mode)
532 {
533     return server_.HandleSetPlayRange(start, end, mode);
534 }
535 
Stop()536 int32_t PlayerServer::PlaybackCompletedState::Stop()
537 {
538     return server_.HandleStop();
539 }
540 
HandleStateChange(int32_t newState)541 void PlayerServer::PlaybackCompletedState::HandleStateChange(int32_t newState)
542 {
543     if (newState == PLAYER_STARTED) {
544         MediaTrace::TraceEnd("PlayerServer::Play", FAKE_POINTER(&server_));
545         server_.ChangeState(server_.playingState_);
546         (void)server_.taskMgr_.MarkTaskDone("completed->started done");
547     } else if (newState == PLAYER_STOPPED) {
548         MediaTrace::TraceEnd("PlayerServer::Stop", FAKE_POINTER(&server_));
549         server_.ChangeState(server_.stoppedState_);
550         server_.lastOpStatus_ = PLAYER_STOPPED;
551         (void)server_.taskMgr_.MarkTaskDone("completed->stopped done");
552     }
553 }
554 
SetPlaybackSpeed(PlaybackRateMode mode)555 int32_t PlayerServer::PlaybackCompletedState::SetPlaybackSpeed(PlaybackRateMode mode)
556 {
557     return server_.HandleSetPlaybackSpeed(mode);
558 }
559 }
560 }
561