// Copyright 2023 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/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator.h"
#import "base/memory/raw_ptr.h"
#import "base/strings/sys_string_conversions.h"
#import "components/prefs/ios/pref_observer_bridge.h"
#import "components/prefs/pref_service.h"
#import "components/signin/public/identity_manager/objc/identity_manager_observer_bridge.h"
#import "ios/chrome/browser/account_picker/ui_bundled/account_picker_selection/account_picker_selection_screen_identity_item_configurator.h"
#import "ios/chrome/browser/shared/model/prefs/pref_names.h"
#import "ios/chrome/browser/shared/public/features/features.h"
#import "ios/chrome/browser/signin/model/chrome_account_manager_service_observer_bridge.h"
#import "ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_account_confirmation_consumer.h"
#import "ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_account_selection_consumer.h"
#import "ios/chrome/browser/ui/settings/downloads/save_to_photos/save_to_photos_settings_mediator_delegate.h"
@interface SaveToPhotosSettingsMediator () <
ChromeAccountManagerServiceObserver,
IdentityManagerObserverBridgeDelegate,
PrefObserverDelegate>
@end
@implementation SaveToPhotosSettingsMediator {
// Account manager service with observer.
raw_ptr<ChromeAccountManagerService> _accountManagerService;
std::unique_ptr<ChromeAccountManagerServiceObserverBridge>
_accountManagerServiceObserver;
// PrefService with registrar and observer.
raw_ptr<PrefService> _prefService;
std::unique_ptr<PrefChangeRegistrar> _prefChangeRegistrar;
std::unique_ptr<PrefObserverBridge> _prefServiceObserver;
// IdentityManager with observer.
raw_ptr<signin::IdentityManager> _identityManager;
std::unique_ptr<signin::IdentityManagerObserverBridge>
_identityManagerObserver;
}
#pragma mark - Initialization
- (instancetype)initWithAccountManagerService:
(ChromeAccountManagerService*)accountManagerService
prefService:(PrefService*)prefService
identityManager:
(signin::IdentityManager*)identityManager {
self = [super init];
if (self) {
CHECK(accountManagerService);
CHECK(prefService);
CHECK(identityManager);
_accountManagerService = accountManagerService;
_accountManagerServiceObserver =
std::make_unique<ChromeAccountManagerServiceObserverBridge>(
self, _accountManagerService);
_prefService = prefService;
_prefChangeRegistrar = std::make_unique<PrefChangeRegistrar>();
_prefChangeRegistrar->Init(_prefService);
_prefServiceObserver = std::make_unique<PrefObserverBridge>(self);
_prefServiceObserver->ObserveChangesForPreference(
prefs::kIosSaveToPhotosDefaultGaiaId, _prefChangeRegistrar.get());
_prefServiceObserver->ObserveChangesForPreference(
prefs::kIosSaveToPhotosSkipAccountPicker, _prefChangeRegistrar.get());
_identityManager = identityManager;
_identityManagerObserver =
std::make_unique<signin::IdentityManagerObserverBridge>(
_identityManager, self);
}
return self;
}
#pragma mark - Setters
- (void)setAccountConfirmationConsumer:
(id<SaveToPhotosSettingsAccountConfirmationConsumer>)
accountConfirmationConsumer {
_accountConfirmationConsumer = accountConfirmationConsumer;
[self updateConsumers];
}
- (void)setAccountSelectionConsumer:
(id<SaveToPhotosSettingsAccountSelectionConsumer>)accountSelectionConsumer {
_accountSelectionConsumer = accountSelectionConsumer;
[self updateConsumers];
}
#pragma mark - Public
- (void)disconnect {
_accountManagerServiceObserver.reset();
_accountManagerService = nullptr;
_prefServiceObserver.reset();
_prefService = nullptr;
_prefChangeRegistrar.reset();
_identityManager = nullptr;
_identityManagerObserver.reset();
}
#pragma mark - SaveToPhotosSettingsMutator
- (void)setSelectedIdentityGaiaID:(NSString*)gaiaID {
CHECK(gaiaID);
_prefService->SetString(prefs::kIosSaveToPhotosDefaultGaiaId,
base::SysNSStringToUTF8(gaiaID));
}
- (void)setAskWhichAccountToUseEveryTime:(BOOL)askEveryTime {
_prefService->SetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker,
!askEveryTime);
}
#pragma mark - ChromeAccountManagerServiceObserver
- (void)identityListChanged {
[self updateConsumers];
}
- (void)identityUpdated:(id<SystemIdentity>)identity {
[self updateConsumers];
}
#pragma mark - PrefObserverDelegate
- (void)onPreferenceChanged:(const std::string&)preferenceName {
[self updateConsumers];
}
#pragma mark - IdentityManagerObserverBridgeDelegate
- (void)onPrimaryAccountChanged:
(const signin::PrimaryAccountChangeEvent&)event {
if (event.GetEventTypeFor(signin::ConsentLevel::kSignin) ==
signin::PrimaryAccountChangeEvent::Type::kCleared) {
[self.delegate hideSaveToPhotosSettings];
return;
}
[self updateConsumers];
}
#pragma mark - Private
// Update consumers with information from `_prefService` and
// `_accountManagerService`.
- (void)updateConsumers {
const std::string savedGaiaID =
_prefService->GetString(prefs::kIosSaveToPhotosDefaultGaiaId);
id<SystemIdentity> savedIdentity =
_accountManagerService->GetIdentityWithGaiaID(savedGaiaID);
// Get signed-in identity.
const CoreAccountInfo primaryAccountInfo =
_identityManager->GetPrimaryAccountInfo(signin::ConsentLevel::kSignin);
id<SystemIdentity> primaryAccount =
_accountManagerService->GetIdentityWithGaiaID(primaryAccountInfo.gaia);
// Update primary consumer with the currently selected Save to Photos account,
// if any.
id<SystemIdentity> selectedIdentity =
savedIdentity ? savedIdentity : primaryAccount;
if (!selectedIdentity) {
// If `selectedIdentity` is nil then there is no identity on the device so
// Save to Photos settings should be hidden.
[self.delegate hideSaveToPhotosSettings];
return;
}
BOOL askEveryTimeSwitchOn =
!_prefService->GetBoolean(prefs::kIosSaveToPhotosSkipAccountPicker);
if (IsSaveToPhotosAccountPickerImprovementEnabled()) {
askEveryTimeSwitchOn = !askEveryTimeSwitchOn;
}
[self.accountConfirmationConsumer
setIdentityButtonAvatar:_accountManagerService
->GetIdentityAvatarWithIdentity(
selectedIdentity,
IdentityAvatarSize::TableViewIcon)
name:selectedIdentity.userFullName
email:selectedIdentity.userEmail
gaiaID:selectedIdentity.gaiaID
askEveryTimeSwitchOn:askEveryTimeSwitchOn];
// Update secondary consumer with the list of accounts on the device and which
// one is currently saved as default to save images to Google Photos, if any.
NSArray<id<SystemIdentity>>* systemIdentities =
_accountManagerService->GetAllIdentities();
NSMutableArray<AccountPickerSelectionScreenIdentityItemConfigurator*>*
identityItemConfigurators = [[NSMutableArray alloc] init];
for (id<SystemIdentity> systemIdentity in systemIdentities) {
AccountPickerSelectionScreenIdentityItemConfigurator* configurator =
[[AccountPickerSelectionScreenIdentityItemConfigurator alloc] init];
configurator.gaiaID = systemIdentity.gaiaID;
configurator.name = systemIdentity.userFullName;
configurator.email = systemIdentity.userEmail;
configurator.avatar = _accountManagerService->GetIdentityAvatarWithIdentity(
systemIdentity, IdentityAvatarSize::TableViewIcon);
configurator.selected =
[systemIdentity.gaiaID isEqual:selectedIdentity.gaiaID];
[identityItemConfigurators addObject:configurator];
}
[self.accountSelectionConsumer
populateAccountsOnDevice:identityItemConfigurators];
}
@end