// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#import "ios/chrome/app/application_delegate/observing_app_state_agent.h"
#import "base/check.h"
#import "ios/chrome/app/application_delegate/app_state.h"
#import "ios/chrome/browser/shared/coordinator/scene/scene_state.h"
@implementation ObservingAppAgent
#pragma mark - AppStateAgent
+ (instancetype)agentFromApp:(AppState*)appState {
for (id agent in appState.connectedAgents) {
if ([agent isMemberOfClass:[self class]]) {
return agent;
}
}
return nil;
}
- (void)setAppState:(AppState*)appState {
// This should only be called once!
DCHECK(!_appState);
_appState = appState;
[appState addObserver:self];
}
@end
#pragma mark - SceneObservingAppAgent
@interface SceneObservingAppAgent ()
// Tracks if the app has already notified that some scenes are in foreground.
// Reset when the app goes background.
@property(nonatomic, assign) BOOL notifiedForeground;
// Tracks if the app has already notified that some scenes are in background.
// Reset when the app goes foreground.
@property(nonatomic, assign) BOOL notifiedBackground;
@end
@implementation SceneObservingAppAgent
- (instancetype)init {
self = [super init];
if (self) {
// The app starts with no connected scenes, so the first event should be
// foreground.
_notifiedBackground = YES;
}
return self;
}
#pragma mark - AppStateAgent
- (void)setAppState:(AppState*)appState {
[super setAppState:appState];
// If there are already connected scenes, start observing them.
for (SceneState* scene in self.appState.connectedScenes) {
[scene addObserver:self];
}
[self notifyOfConvenienceEventsIfNecessary];
}
#pragma mark - AppStateObserver
- (void)appState:(AppState*)appState sceneConnected:(SceneState*)sceneState {
[sceneState addObserver:self];
}
- (void)appState:(AppState*)appState
didTransitionFromInitStage:(InitStage)previousInitStage {
if (appState.initStage == InitStageFinal) {
[self notifyOfConvenienceEventsIfNecessary];
}
}
#pragma mark - SceneStateObserver
- (void)sceneState:(SceneState*)sceneState
transitionedToActivationLevel:(SceneActivationLevel)level {
if (self.appState.initStage < InitStageFinal) {
return;
}
[self notifyOfConvenienceEventsIfNecessary];
}
- (void)notifyOfConvenienceEventsIfNecessary {
if (self.appState.foregroundScenes.count > 0 && !self.notifiedForeground) {
self.notifiedForeground = YES;
self.notifiedBackground = NO;
[self appDidEnterForeground];
}
if (self.appState.foregroundScenes.count == 0 && !self.notifiedBackground) {
self.notifiedBackground = YES;
self.notifiedForeground = NO;
[self appDidEnterBackground];
}
}
#pragma mark - template methods
- (void)appDidEnterForeground {
}
- (void)appDidEnterBackground {
}
@end