blob: 56081eaeac7a8c39fabfa100d2002a908914f9e6 [file] [log] [blame]
// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/page_visibility/page_visibility_state.h"
namespace cobalt {
namespace page_visibility {
namespace {
// Converts an ApplicationState to a VisibilityState.
VisibilityState ToVisibilityState(base::ApplicationState state) {
switch (state) {
case base::kApplicationStatePreloading:
return kVisibilityStatePrerender;
case base::kApplicationStateStarted:
case base::kApplicationStatePaused:
return kVisibilityStateVisible;
case base::kApplicationStateSuspended:
case base::kApplicationStateStopped:
return kVisibilityStateHidden;
default:
NOTREACHED() << "Invalid Application State: " << state;
return kVisibilityStateHidden;
}
}
bool HasFocus(base::ApplicationState state) {
switch (state) {
case base::kApplicationStateStarted:
return true;
case base::kApplicationStatePreloading:
case base::kApplicationStatePaused:
case base::kApplicationStateSuspended:
case base::kApplicationStateStopped:
return false;
default:
NOTREACHED() << "Invalid Application State: " << state;
return false;
}
}
} // namespace
PageVisibilityState::PageVisibilityState()
: application_state_(base::kApplicationStateStarted) {}
PageVisibilityState::PageVisibilityState(
base::ApplicationState initial_application_state)
: application_state_(initial_application_state) {
DCHECK((application_state_ == base::kApplicationStateStarted) ||
(application_state_ == base::kApplicationStatePreloading) ||
(application_state_ == base::kApplicationStatePaused))
<< "application_state_=" << application_state_;
}
bool PageVisibilityState::HasWindowFocus() const {
return HasFocus(application_state());
}
VisibilityState PageVisibilityState::GetVisibilityState() const {
return ToVisibilityState(application_state());
}
void PageVisibilityState::SetApplicationState(base::ApplicationState state) {
if (application_state_ == state) {
DLOG(WARNING) << __FUNCTION__ << ": Attempt to re-enter "
<< application_state_;
return;
}
// Audit that the transitions are correct.
if (DLOG_IS_ON(FATAL)) {
switch (application_state_) {
case base::kApplicationStatePaused:
DCHECK(state == base::kApplicationStateSuspended ||
state == base::kApplicationStateStarted);
break;
case base::kApplicationStatePreloading:
DCHECK(state == base::kApplicationStateSuspended ||
state == base::kApplicationStateStarted);
case base::kApplicationStateStarted:
DCHECK(state == base::kApplicationStatePaused);
break;
case base::kApplicationStateStopped:
DCHECK(state == base::kApplicationStatePreloading ||
state == base::kApplicationStateStarted);
break;
case base::kApplicationStateSuspended:
DCHECK(state == base::kApplicationStatePaused ||
state == base::kApplicationStateStopped);
break;
default:
NOTREACHED() << application_state_;
break;
}
}
bool old_has_focus = HasFocus(application_state_);
VisibilityState old_visibility_state = ToVisibilityState(application_state_);
application_state_ = state;
bool has_focus = HasFocus(application_state_);
VisibilityState visibility_state = ToVisibilityState(application_state_);
bool focus_changed = has_focus != old_has_focus;
bool visibility_state_changed = visibility_state != old_visibility_state;
if (focus_changed && has_focus) {
// If going to a focused state, dispatch the visibility state first.
if (visibility_state_changed) {
DispatchVisibilityStateChanged(visibility_state);
}
DispatchWindowFocusChanged(has_focus);
return;
}
// Otherwise, we should dispatch the focus state first.
if (focus_changed) {
DispatchWindowFocusChanged(has_focus);
}
if (visibility_state_changed) {
DispatchVisibilityStateChanged(visibility_state);
}
}
void PageVisibilityState::DispatchWindowFocusChanged(bool has_focus) {
FOR_EACH_OBSERVER(Observer, observer_list_, OnWindowFocusChanged(has_focus));
}
void PageVisibilityState::DispatchVisibilityStateChanged(
VisibilityState visibility_state) {
FOR_EACH_OBSERVER(Observer, observer_list_,
OnVisibilityStateChanged(visibility_state));
}
} // namespace page_visibility
} // namespace cobalt