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