OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" | 5 #import "ios/chrome/browser/ui/settings/settings_collection_view_controller.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #import "base/mac/foundation_util.h" | 9 #import "base/mac/foundation_util.h" |
| 10 #include "base/metrics/histogram_macros.h" |
10 #include "base/metrics/user_metrics.h" | 11 #include "base/metrics/user_metrics.h" |
11 #include "base/scoped_observer.h" | 12 #include "base/scoped_observer.h" |
12 #include "base/strings/sys_string_conversions.h" | 13 #include "base/strings/sys_string_conversions.h" |
13 #include "components/autofill/core/common/autofill_pref_names.h" | 14 #include "components/autofill/core/common/autofill_pref_names.h" |
14 #include "components/browser_sync/profile_sync_service.h" | 15 #include "components/browser_sync/profile_sync_service.h" |
15 #include "components/keyed_service/core/service_access_type.h" | 16 #include "components/keyed_service/core/service_access_type.h" |
16 #include "components/password_manager/core/browser/password_store.h" | 17 #include "components/password_manager/core/browser/password_store.h" |
17 #include "components/password_manager/core/common/password_manager_pref_names.h" | 18 #include "components/password_manager/core/common/password_manager_pref_names.h" |
| 19 #include "components/pref_registry/pref_registry_syncable.h" |
18 #include "components/prefs/pref_change_registrar.h" | 20 #include "components/prefs/pref_change_registrar.h" |
19 #include "components/prefs/pref_service.h" | 21 #include "components/prefs/pref_service.h" |
20 #include "components/search_engines/util.h" | 22 #include "components/search_engines/util.h" |
21 #include "components/signin/core/browser/signin_manager.h" | 23 #include "components/signin/core/browser/signin_manager.h" |
22 #include "components/signin/core/common/signin_pref_names.h" | 24 #include "components/signin/core/common/signin_pref_names.h" |
23 #include "components/strings/grit/components_strings.h" | 25 #include "components/strings/grit/components_strings.h" |
24 #include "ios/chrome/browser/application_context.h" | 26 #include "ios/chrome/browser/application_context.h" |
25 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" | 27 #include "ios/chrome/browser/browser_state/chrome_browser_state.h" |
26 #include "ios/chrome/browser/browser_state/chrome_browser_state_removal_controll
er.h" | 28 #include "ios/chrome/browser/browser_state/chrome_browser_state_removal_controll
er.h" |
27 #include "ios/chrome/browser/experimental_flags.h" | 29 #include "ios/chrome/browser/experimental_flags.h" |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
89 | 91 |
90 @interface SettingsCollectionViewController (NotificationBridgeDelegate) | 92 @interface SettingsCollectionViewController (NotificationBridgeDelegate) |
91 // Notifies this controller that the sign in state has changed. | 93 // Notifies this controller that the sign in state has changed. |
92 - (void)onSignInStateChanged; | 94 - (void)onSignInStateChanged; |
93 @end | 95 @end |
94 | 96 |
95 namespace { | 97 namespace { |
96 | 98 |
97 const CGFloat kAccountProfilePhotoDimension = 40.0f; | 99 const CGFloat kAccountProfilePhotoDimension = 40.0f; |
98 | 100 |
| 101 const int kAutomaticSigninPromoViewDismissCount = 20; |
| 102 |
99 typedef NS_ENUM(NSInteger, SectionIdentifier) { | 103 typedef NS_ENUM(NSInteger, SectionIdentifier) { |
100 SectionIdentifierSignIn = kSectionIdentifierEnumZero, | 104 SectionIdentifierSignIn = kSectionIdentifierEnumZero, |
101 SectionIdentifierBasics, | 105 SectionIdentifierBasics, |
102 SectionIdentifierAdvanced, | 106 SectionIdentifierAdvanced, |
103 SectionIdentifierInfo, | 107 SectionIdentifierInfo, |
104 SectionIdentifierDebug, | 108 SectionIdentifierDebug, |
105 }; | 109 }; |
106 | 110 |
107 typedef NS_ENUM(NSInteger, ItemType) { | 111 typedef NS_ENUM(NSInteger, ItemType) { |
108 ItemTypeSignInButton = kItemTypeEnumZero, | 112 ItemTypeSignInButton = kItemTypeEnumZero, |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 // TODO(crbug.com/662435): Refactor PrefObserverBridge so it owns the | 221 // TODO(crbug.com/662435): Refactor PrefObserverBridge so it owns the |
218 // PrefChangeRegistrar. | 222 // PrefChangeRegistrar. |
219 // Registrar for pref changes notifications. | 223 // Registrar for pref changes notifications. |
220 PrefChangeRegistrar _prefChangeRegistrar; | 224 PrefChangeRegistrar _prefChangeRegistrar; |
221 | 225 |
222 // Updatable Items. | 226 // Updatable Items. |
223 CollectionViewDetailItem* _voiceSearchDetailItem; | 227 CollectionViewDetailItem* _voiceSearchDetailItem; |
224 CollectionViewDetailItem* _defaultSearchEngineItem; | 228 CollectionViewDetailItem* _defaultSearchEngineItem; |
225 CollectionViewDetailItem* _savePasswordsDetailItem; | 229 CollectionViewDetailItem* _savePasswordsDetailItem; |
226 CollectionViewDetailItem* _autoFillDetailItem; | 230 CollectionViewDetailItem* _autoFillDetailItem; |
| 231 |
| 232 // YES if the user used at least once the sign-in promo view buttons. |
| 233 BOOL _signinStarted; |
227 } | 234 } |
228 | 235 |
229 // Stops observing browser state services. This is required during the shutdown | 236 // Stops observing browser state services. This is required during the shutdown |
230 // phase to avoid observing services for a profile that is being killed. | 237 // phase to avoid observing services for a profile that is being killed. |
231 - (void)stopBrowserStateServiceObservers; | 238 - (void)stopBrowserStateServiceObservers; |
232 | 239 |
233 @end | 240 @end |
234 | 241 |
235 @implementation SettingsCollectionViewController | 242 @implementation SettingsCollectionViewController |
236 @synthesize dispatcher = _dispatcher; | 243 @synthesize dispatcher = _dispatcher; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
303 #pragma mark View lifecycle | 310 #pragma mark View lifecycle |
304 | 311 |
305 // TODO(crbug.com/661915): Refactor TemplateURLObserver and re-implement this so | 312 // TODO(crbug.com/661915): Refactor TemplateURLObserver and re-implement this so |
306 // it observes the default search engine name instead of reloading on | 313 // it observes the default search engine name instead of reloading on |
307 // ViewWillAppear. | 314 // ViewWillAppear. |
308 - (void)viewWillAppear:(BOOL)animated { | 315 - (void)viewWillAppear:(BOOL)animated { |
309 [super viewWillAppear:animated]; | 316 [super viewWillAppear:animated]; |
310 [self updateSearchCell]; | 317 [self updateSearchCell]; |
311 } | 318 } |
312 | 319 |
| 320 - (void)viewDidDisappear:(BOOL)animated { |
| 321 [super viewDidDisappear:animated]; |
| 322 if (!_signinStarted && _signinPromoViewMediator) { |
| 323 PrefService* prefs = _browserState->GetPrefs(); |
| 324 int displayedCount = |
| 325 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); |
| 326 UMA_HISTOGRAM_COUNTS_100( |
| 327 "MobileSignInPromo.SettingsManager.ImpressionsTilDismiss", |
| 328 displayedCount); |
| 329 } |
| 330 } |
| 331 |
313 #pragma mark SettingsRootCollectionViewController | 332 #pragma mark SettingsRootCollectionViewController |
314 | 333 |
315 - (void)loadModel { | 334 - (void)loadModel { |
316 [super loadModel]; | 335 [super loadModel]; |
317 | 336 |
318 CollectionViewModel* model = self.collectionViewModel; | 337 CollectionViewModel* model = self.collectionViewModel; |
319 | 338 |
320 // Sign in/Account section | 339 // Sign in/Account section |
321 [model addSectionWithIdentifier:SectionIdentifierSignIn]; | 340 [model addSectionWithIdentifier:SectionIdentifierSignIn]; |
322 AuthenticationService* authService = | 341 AuthenticationService* authService = |
323 AuthenticationServiceFactory::GetForBrowserState(_browserState); | 342 AuthenticationServiceFactory::GetForBrowserState(_browserState); |
324 if (!authService->IsAuthenticated()) { | 343 if (!authService->IsAuthenticated()) { |
325 if (!_hasRecordedSigninImpression) { | 344 if (!_hasRecordedSigninImpression) { |
326 // Once the Settings are open, this button impression will at most be | 345 // Once the Settings are open, this button impression will at most be |
327 // recorded once until they are closed. | 346 // recorded once until they are closed. |
328 base::RecordAction( | 347 base::RecordAction( |
329 base::UserMetricsAction("Signin_Impression_FromSettings")); | 348 base::UserMetricsAction("Signin_Impression_FromSettings")); |
330 _hasRecordedSigninImpression = YES; | 349 _hasRecordedSigninImpression = YES; |
331 } | 350 } |
332 if (experimental_flags::IsSigninPromoEnabled()) { | 351 PrefService* prefs = _browserState->GetPrefs(); |
| 352 int displayedCount = |
| 353 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); |
| 354 if (experimental_flags::IsSigninPromoEnabled() && |
| 355 displayedCount < kAutomaticSigninPromoViewDismissCount) { |
333 _signinPromoViewMediator = | 356 _signinPromoViewMediator = |
334 [[SigninPromoViewMediator alloc] initWithBrowserState:_browserState]; | 357 [[SigninPromoViewMediator alloc] initWithBrowserState:_browserState]; |
335 _signinPromoViewMediator.consumer = self; | 358 _signinPromoViewMediator.consumer = self; |
| 359 prefs->SetInteger(prefs::kIosSettingsSigninPromoDisplayedCount, |
| 360 displayedCount + 1); |
336 } | 361 } |
337 [model addItem:[self signInTextItem] | 362 [model addItem:[self signInTextItem] |
338 toSectionWithIdentifier:SectionIdentifierSignIn]; | 363 toSectionWithIdentifier:SectionIdentifierSignIn]; |
339 } else { | 364 } else { |
340 _signinPromoViewMediator = nil; | 365 _signinPromoViewMediator = nil; |
341 [model addItem:[self accountCellItem] | 366 [model addItem:[self accountCellItem] |
342 toSectionWithIdentifier:SectionIdentifierSignIn]; | 367 toSectionWithIdentifier:SectionIdentifierSignIn]; |
343 } | 368 } |
344 | 369 |
345 // Basics section | 370 // Basics section |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 [model addItem:[self showAutofillTypePredictionsSwitchItem] | 430 [model addItem:[self showAutofillTypePredictionsSwitchItem] |
406 toSectionWithIdentifier:SectionIdentifierDebug]; | 431 toSectionWithIdentifier:SectionIdentifierDebug]; |
407 [model addItem:[self materialCatalogDetailItem] | 432 [model addItem:[self materialCatalogDetailItem] |
408 toSectionWithIdentifier:SectionIdentifierDebug]; | 433 toSectionWithIdentifier:SectionIdentifierDebug]; |
409 #endif // CHROMIUM_BUILD && !defined(NDEBUG) | 434 #endif // CHROMIUM_BUILD && !defined(NDEBUG) |
410 } | 435 } |
411 | 436 |
412 #pragma mark - Model Items | 437 #pragma mark - Model Items |
413 | 438 |
414 - (CollectionViewItem*)signInTextItem { | 439 - (CollectionViewItem*)signInTextItem { |
415 if (experimental_flags::IsSigninPromoEnabled()) { | 440 if (_signinPromoViewMediator) { |
416 DCHECK(_signinPromoViewMediator); | |
417 SigninPromoItem* signinPromoItem = | 441 SigninPromoItem* signinPromoItem = |
418 [[SigninPromoItem alloc] initWithType:ItemTypeSigninPromo]; | 442 [[SigninPromoItem alloc] initWithType:ItemTypeSigninPromo]; |
419 signinPromoItem.configurator = | 443 signinPromoItem.configurator = |
420 [_signinPromoViewMediator createConfigurator]; | 444 [_signinPromoViewMediator createConfigurator]; |
421 return signinPromoItem; | 445 return signinPromoItem; |
422 } | 446 } |
423 AccountSignInItem* signInTextItem = | 447 AccountSignInItem* signInTextItem = |
424 [[AccountSignInItem alloc] initWithType:ItemTypeSignInButton]; | 448 [[AccountSignInItem alloc] initWithType:ItemTypeSignInButton]; |
425 signInTextItem.accessibilityIdentifier = kSettingsSignInCellId; | 449 signInTextItem.accessibilityIdentifier = kSettingsSignInCellId; |
426 UIImage* image = CircularImageFromImage(ios::GetChromeBrowserProvider() | 450 UIImage* image = CircularImageFromImage(ios::GetChromeBrowserProvider() |
(...skipping 727 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1154 [self reconfigureCellsForItems:@[ signinPromoItem ]]; | 1178 [self reconfigureCellsForItems:@[ signinPromoItem ]]; |
1155 if (identityChanged) | 1179 if (identityChanged) |
1156 [self.collectionViewLayout invalidateLayout]; | 1180 [self.collectionViewLayout invalidateLayout]; |
1157 } | 1181 } |
1158 } | 1182 } |
1159 | 1183 |
1160 #pragma mark - SigninPromoViewDelegate | 1184 #pragma mark - SigninPromoViewDelegate |
1161 | 1185 |
1162 - (void)signinPromoViewDidTapSigninWithNewAccount: | 1186 - (void)signinPromoViewDidTapSigninWithNewAccount: |
1163 (SigninPromoView*)signinPromoView { | 1187 (SigninPromoView*)signinPromoView { |
| 1188 [self sendImpressionsTilSigninButtonsHistogram]; |
1164 DCHECK(!_signinPromoViewMediator.defaultIdentity); | 1189 DCHECK(!_signinPromoViewMediator.defaultIdentity); |
1165 base::RecordAction( | 1190 base::RecordAction( |
1166 base::UserMetricsAction("Signin_SigninNewAccount_FromSettings")); | 1191 base::UserMetricsAction("Signin_SigninNewAccount_FromSettings")); |
1167 [self showSignInWithIdentity:nil | 1192 [self showSignInWithIdentity:nil |
1168 promoAction:signin_metrics::PromoAction:: | 1193 promoAction:signin_metrics::PromoAction:: |
1169 PROMO_ACTION_NEW_ACCOUNT]; | 1194 PROMO_ACTION_NEW_ACCOUNT]; |
1170 } | 1195 } |
1171 | 1196 |
1172 - (void)signinPromoViewDidTapSigninWithDefaultAccount: | 1197 - (void)signinPromoViewDidTapSigninWithDefaultAccount: |
1173 (SigninPromoView*)signinPromoView { | 1198 (SigninPromoView*)signinPromoView { |
| 1199 [self sendImpressionsTilSigninButtonsHistogram]; |
1174 ChromeIdentity* identity = _signinPromoViewMediator.defaultIdentity; | 1200 ChromeIdentity* identity = _signinPromoViewMediator.defaultIdentity; |
1175 DCHECK(identity); | 1201 DCHECK(identity); |
1176 base::RecordAction( | 1202 base::RecordAction( |
1177 base::UserMetricsAction("Signin_SigninWithDefault_FromSettings")); | 1203 base::UserMetricsAction("Signin_SigninWithDefault_FromSettings")); |
1178 [self showSignInWithIdentity:identity | 1204 [self showSignInWithIdentity:identity |
1179 promoAction:signin_metrics::PromoAction:: | 1205 promoAction:signin_metrics::PromoAction:: |
1180 PROMO_ACTION_WITH_DEFAULT]; | 1206 PROMO_ACTION_WITH_DEFAULT]; |
1181 } | 1207 } |
1182 | 1208 |
1183 - (void)signinPromoViewDidTapSigninWithOtherAccount: | 1209 - (void)signinPromoViewDidTapSigninWithOtherAccount: |
1184 (SigninPromoView*)signinPromoView { | 1210 (SigninPromoView*)signinPromoView { |
| 1211 [self sendImpressionsTilSigninButtonsHistogram]; |
1185 DCHECK(_signinPromoViewMediator.defaultIdentity); | 1212 DCHECK(_signinPromoViewMediator.defaultIdentity); |
1186 base::RecordAction( | 1213 base::RecordAction( |
1187 base::UserMetricsAction("Signin_SigninNotDefault_FromSettings")); | 1214 base::UserMetricsAction("Signin_SigninNotDefault_FromSettings")); |
1188 [self showSignInWithIdentity:nil | 1215 [self showSignInWithIdentity:nil |
1189 promoAction:signin_metrics::PromoAction:: | 1216 promoAction:signin_metrics::PromoAction:: |
1190 PROMO_ACTION_NOT_DEFAULT]; | 1217 PROMO_ACTION_NOT_DEFAULT]; |
1191 } | 1218 } |
1192 | 1219 |
| 1220 #pragma mark - Metrics |
| 1221 |
| 1222 - (void)sendImpressionsTilSigninButtonsHistogram { |
| 1223 _signinStarted = YES; |
| 1224 PrefService* prefs = _browserState->GetPrefs(); |
| 1225 int displayedCount = |
| 1226 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount); |
| 1227 UMA_HISTOGRAM_COUNTS_100( |
| 1228 "MobileSignInPromo.SettingsManager.ImpressionsTilSigninButtons", |
| 1229 displayedCount); |
| 1230 } |
| 1231 |
1193 @end | 1232 @end |
OLD | NEW |