| // Copyright 2022 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/browser/sync/sync_error_browser_agent.h" |
| |
| #import "ios/chrome/browser/settings/sync/utils/sync_util.h" |
| #import "ios/chrome/browser/shared/model/browser_state/chrome_browser_state.h" |
| #import "ios/chrome/browser/shared/model/web_state_list/web_state_list.h" |
| #import "ios/chrome/browser/ui/authentication/re_signin_infobar_delegate.h" |
| #import "ios/chrome/browser/ui/authentication/signin_presenter.h" |
| |
| #if !defined(__has_feature) || !__has_feature(objc_arc) |
| #error "This file requires ARC support." |
| #endif |
| |
| BROWSER_USER_DATA_KEY_IMPL(SyncErrorBrowserAgent) |
| |
| SyncErrorBrowserAgent::SyncErrorBrowserAgent(Browser* browser) |
| : browser_(browser) { |
| DCHECK(browser_); |
| browser->AddObserver(this); |
| browser->GetWebStateList()->AddObserver(this); |
| } |
| |
| SyncErrorBrowserAgent::~SyncErrorBrowserAgent() { |
| DCHECK(!browser_); |
| } |
| |
| void SyncErrorBrowserAgent::SetUIProviders( |
| id<SigninPresenter> signin_presenter_provider, |
| id<SyncPresenter> sync_presenter_provider) { |
| DCHECK(signin_presenter_provider); |
| DCHECK(sync_presenter_provider); |
| signin_presenter_provider_ = signin_presenter_provider; |
| sync_presenter_provider_ = sync_presenter_provider; |
| |
| // Re-evaluate all web states. |
| web_state_observations_.RemoveAllObservations(); |
| WebStateList* web_state_list = browser_->GetWebStateList(); |
| for (int i = 0; i < web_state_list->count(); i++) { |
| web::WebState* web_state = web_state_list->GetWebStateAt(i); |
| CreateReSignInInfoBarDelegate(web_state); |
| } |
| } |
| |
| void SyncErrorBrowserAgent::ClearUIProviders() { |
| signin_presenter_provider_ = nil; |
| sync_presenter_provider_ = nil; |
| } |
| |
| #pragma mark - BrowserObserver |
| |
| void SyncErrorBrowserAgent::BrowserDestroyed(Browser* browser) { |
| DCHECK_EQ(browser, browser_); |
| browser->GetWebStateList()->RemoveObserver(this); |
| browser->RemoveObserver(this); |
| browser_ = nullptr; |
| } |
| |
| #pragma mark - WebStateListObserver |
| |
| void SyncErrorBrowserAgent::WebStateListChanged( |
| WebStateList* web_state_list, |
| const WebStateListChange& change, |
| const WebStateSelection& selection) { |
| switch (change.type()) { |
| case WebStateListChange::Type::kSelectionOnly: |
| // Do nothing when a WebState is selected and its status is updated. |
| break; |
| case WebStateListChange::Type::kDetach: |
| // TODO(crbug.com/1442546): Move the implementation from |
| // WebStateDetachedAt() to here. |
| break; |
| case WebStateListChange::Type::kMove: |
| // Do nothing when a WebState is moved. |
| break; |
| case WebStateListChange::Type::kReplace: { |
| const WebStateListChangeReplace& replace_change = |
| change.As<WebStateListChangeReplace>(); |
| web::WebState* replaced_web_state = replace_change.replaced_web_state(); |
| if (!replaced_web_state->IsRealized()) { |
| web_state_observations_.RemoveObservation(replaced_web_state); |
| } |
| CreateReSignInInfoBarDelegate(replace_change.inserted_web_state()); |
| break; |
| } |
| case WebStateListChange::Type::kInsert: { |
| const WebStateListChangeInsert& insert_change = |
| change.As<WebStateListChangeInsert>(); |
| CreateReSignInInfoBarDelegate(insert_change.inserted_web_state()); |
| break; |
| } |
| } |
| } |
| |
| void SyncErrorBrowserAgent::WebStateDetachedAt(WebStateList* web_state_list, |
| web::WebState* web_state, |
| int index) { |
| if (!web_state->IsRealized()) { |
| web_state_observations_.RemoveObservation(web_state); |
| } |
| } |
| |
| void SyncErrorBrowserAgent::WebStateDestroyed(web::WebState* web_state) { |
| web_state_observations_.RemoveObservation(web_state); |
| } |
| |
| void SyncErrorBrowserAgent::WebStateRealized(web::WebState* web_state) { |
| web_state_observations_.RemoveObservation(web_state); |
| CreateReSignInInfoBarDelegate(web_state); |
| } |
| |
| void SyncErrorBrowserAgent::CreateReSignInInfoBarDelegate( |
| web::WebState* web_state) { |
| if (!web_state->IsRealized()) { |
| web_state_observations_.AddObservation(web_state); |
| return; |
| } |
| |
| if (!signin_presenter_provider_ || !sync_presenter_provider_) { |
| return; |
| } |
| |
| ChromeBrowserState* browser_state = browser_->GetBrowserState(); |
| if (!ReSignInInfoBarDelegate::Create(browser_state, web_state, |
| signin_presenter_provider_)) { |
| DisplaySyncErrors(browser_state, web_state, sync_presenter_provider_); |
| } |
| } |