Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(261)

Side by Side Diff: ios/chrome/browser/ui/settings/settings_collection_view_controller.mm

Issue 2953083005: Implementing sign-in promo histograms for settings (Closed)
Patch Set: Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « ios/chrome/browser/ui/settings/BUILD.gn ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
88 90
89 @interface SettingsCollectionViewController (NotificationBridgeDelegate) 91 @interface SettingsCollectionViewController (NotificationBridgeDelegate)
90 // Notifies this controller that the sign in state has changed. 92 // Notifies this controller that the sign in state has changed.
91 - (void)onSignInStateChanged; 93 - (void)onSignInStateChanged;
92 @end 94 @end
93 95
94 namespace { 96 namespace {
95 97
96 const CGFloat kAccountProfilePhotoDimension = 40.0f; 98 const CGFloat kAccountProfilePhotoDimension = 40.0f;
97 99
100 const int kAutomaticSigninPromoViewDismissCount = 20;
101
98 typedef NS_ENUM(NSInteger, SectionIdentifier) { 102 typedef NS_ENUM(NSInteger, SectionIdentifier) {
99 SectionIdentifierSignIn = kSectionIdentifierEnumZero, 103 SectionIdentifierSignIn = kSectionIdentifierEnumZero,
100 SectionIdentifierBasics, 104 SectionIdentifierBasics,
101 SectionIdentifierAdvanced, 105 SectionIdentifierAdvanced,
102 SectionIdentifierInfo, 106 SectionIdentifierInfo,
103 SectionIdentifierDebug, 107 SectionIdentifierDebug,
104 }; 108 };
105 109
106 typedef NS_ENUM(NSInteger, ItemType) { 110 typedef NS_ENUM(NSInteger, ItemType) {
107 ItemTypeSignInButton = kItemTypeEnumZero, 111 ItemTypeSignInButton = kItemTypeEnumZero,
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 // TODO(crbug.com/662435): Refactor PrefObserverBridge so it owns the 219 // TODO(crbug.com/662435): Refactor PrefObserverBridge so it owns the
216 // PrefChangeRegistrar. 220 // PrefChangeRegistrar.
217 // Registrar for pref changes notifications. 221 // Registrar for pref changes notifications.
218 PrefChangeRegistrar _prefChangeRegistrar; 222 PrefChangeRegistrar _prefChangeRegistrar;
219 223
220 // Updatable Items. 224 // Updatable Items.
221 CollectionViewDetailItem* _voiceSearchDetailItem; 225 CollectionViewDetailItem* _voiceSearchDetailItem;
222 CollectionViewDetailItem* _defaultSearchEngineItem; 226 CollectionViewDetailItem* _defaultSearchEngineItem;
223 CollectionViewDetailItem* _savePasswordsDetailItem; 227 CollectionViewDetailItem* _savePasswordsDetailItem;
224 CollectionViewDetailItem* _autoFillDetailItem; 228 CollectionViewDetailItem* _autoFillDetailItem;
229
230 // YES if the user used at least once the sign-in promo view buttons.
231 BOOL _signinStarted;
225 } 232 }
226 233
227 // Stops observing browser state services. This is required during the shutdown 234 // Stops observing browser state services. This is required during the shutdown
228 // phase to avoid observing services for a profile that is being killed. 235 // phase to avoid observing services for a profile that is being killed.
229 - (void)stopBrowserStateServiceObservers; 236 - (void)stopBrowserStateServiceObservers;
230 237
231 @end 238 @end
232 239
233 @implementation SettingsCollectionViewController 240 @implementation SettingsCollectionViewController
234 241
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 #pragma mark View lifecycle 305 #pragma mark View lifecycle
299 306
300 // TODO(crbug.com/661915): Refactor TemplateURLObserver and re-implement this so 307 // TODO(crbug.com/661915): Refactor TemplateURLObserver and re-implement this so
301 // it observes the default search engine name instead of reloading on 308 // it observes the default search engine name instead of reloading on
302 // ViewWillAppear. 309 // ViewWillAppear.
303 - (void)viewWillAppear:(BOOL)animated { 310 - (void)viewWillAppear:(BOOL)animated {
304 [super viewWillAppear:animated]; 311 [super viewWillAppear:animated];
305 [self updateSearchCell]; 312 [self updateSearchCell];
306 } 313 }
307 314
315 - (void)viewDidDisappear:(BOOL)animated {
316 [super viewDidDisappear:animated];
317 if (!_signinStarted && _signinPromoViewMediator) {
318 PrefService* prefs = _browserState->GetPrefs();
319 int displayedCount =
320 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount);
321 UMA_HISTOGRAM_COUNTS_100("MobileSignInPromo.SettingsManager.DismissalCount",
322 displayedCount);
323 }
324 }
325
308 #pragma mark SettingsRootCollectionViewController 326 #pragma mark SettingsRootCollectionViewController
309 327
310 - (void)loadModel { 328 - (void)loadModel {
311 [super loadModel]; 329 [super loadModel];
312 330
313 CollectionViewModel* model = self.collectionViewModel; 331 CollectionViewModel* model = self.collectionViewModel;
314 332
315 // Sign in/Account section 333 // Sign in/Account section
316 [model addSectionWithIdentifier:SectionIdentifierSignIn]; 334 [model addSectionWithIdentifier:SectionIdentifierSignIn];
317 AuthenticationService* authService = 335 AuthenticationService* authService =
318 AuthenticationServiceFactory::GetForBrowserState(_browserState); 336 AuthenticationServiceFactory::GetForBrowserState(_browserState);
319 if (!authService->IsAuthenticated()) { 337 if (!authService->IsAuthenticated()) {
320 if (!_hasRecordedSigninImpression) { 338 if (!_hasRecordedSigninImpression) {
321 // Once the Settings are open, this button impression will at most be 339 // Once the Settings are open, this button impression will at most be
322 // recorded once until they are closed. 340 // recorded once until they are closed.
323 base::RecordAction( 341 base::RecordAction(
324 base::UserMetricsAction("Signin_Impression_FromSettings")); 342 base::UserMetricsAction("Signin_Impression_FromSettings"));
325 _hasRecordedSigninImpression = YES; 343 _hasRecordedSigninImpression = YES;
326 } 344 }
327 if (experimental_flags::IsSigninPromoEnabled()) { 345 PrefService* prefs = _browserState->GetPrefs();
346 int displayedCount =
347 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount);
348 if (experimental_flags::IsSigninPromoEnabled() &&
349 displayedCount < kAutomaticSigninPromoViewDismissCount) {
328 _signinPromoViewMediator = 350 _signinPromoViewMediator =
329 [[SigninPromoViewMediator alloc] initWithBrowserState:_browserState]; 351 [[SigninPromoViewMediator alloc] initWithBrowserState:_browserState];
330 _signinPromoViewMediator.consumer = self; 352 _signinPromoViewMediator.consumer = self;
353 ++displayedCount;
sdefresne 2017/06/26 06:34:35 nit: it is clearer in my opinion to just pass "dis
jlebel 2017/06/26 19:19:21 Done.
354 prefs->SetInteger(prefs::kIosSettingsSigninPromoDisplayedCount,
355 displayedCount);
331 } 356 }
332 [model addItem:[self signInTextItem] 357 [model addItem:[self signInTextItem]
333 toSectionWithIdentifier:SectionIdentifierSignIn]; 358 toSectionWithIdentifier:SectionIdentifierSignIn];
334 } else { 359 } else {
335 _signinPromoViewMediator = nil; 360 _signinPromoViewMediator = nil;
336 [model addItem:[self accountCellItem] 361 [model addItem:[self accountCellItem]
337 toSectionWithIdentifier:SectionIdentifierSignIn]; 362 toSectionWithIdentifier:SectionIdentifierSignIn];
338 } 363 }
339 364
340 // Basics section 365 // Basics section
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
400 [model addItem:[self showAutofillTypePredictionsSwitchItem] 425 [model addItem:[self showAutofillTypePredictionsSwitchItem]
401 toSectionWithIdentifier:SectionIdentifierDebug]; 426 toSectionWithIdentifier:SectionIdentifierDebug];
402 [model addItem:[self materialCatalogDetailItem] 427 [model addItem:[self materialCatalogDetailItem]
403 toSectionWithIdentifier:SectionIdentifierDebug]; 428 toSectionWithIdentifier:SectionIdentifierDebug];
404 #endif // CHROMIUM_BUILD && !defined(NDEBUG) 429 #endif // CHROMIUM_BUILD && !defined(NDEBUG)
405 } 430 }
406 431
407 #pragma mark - Model Items 432 #pragma mark - Model Items
408 433
409 - (CollectionViewItem*)signInTextItem { 434 - (CollectionViewItem*)signInTextItem {
410 if (experimental_flags::IsSigninPromoEnabled()) { 435 if (_signinPromoViewMediator) {
411 DCHECK(_signinPromoViewMediator);
412 SigninPromoItem* signinPromoItem = 436 SigninPromoItem* signinPromoItem =
413 [[SigninPromoItem alloc] initWithType:ItemTypeSigninPromo]; 437 [[SigninPromoItem alloc] initWithType:ItemTypeSigninPromo];
414 signinPromoItem.configurator = 438 signinPromoItem.configurator =
415 [_signinPromoViewMediator createConfigurator]; 439 [_signinPromoViewMediator createConfigurator];
416 return signinPromoItem; 440 return signinPromoItem;
417 } 441 }
418 AccountSignInItem* signInTextItem = 442 AccountSignInItem* signInTextItem =
419 [[AccountSignInItem alloc] initWithType:ItemTypeSignInButton]; 443 [[AccountSignInItem alloc] initWithType:ItemTypeSignInButton];
420 signInTextItem.accessibilityIdentifier = kSettingsSignInCellId; 444 signInTextItem.accessibilityIdentifier = kSettingsSignInCellId;
421 UIImage* image = CircularImageFromImage(ios::GetChromeBrowserProvider() 445 UIImage* image = CircularImageFromImage(ios::GetChromeBrowserProvider()
(...skipping 719 matching lines...) Expand 10 before | Expand all | Expand 10 after
1141 [self reconfigureCellsForItems:@[ signinPromoItem ]]; 1165 [self reconfigureCellsForItems:@[ signinPromoItem ]];
1142 if (identityChanged) 1166 if (identityChanged)
1143 [self.collectionViewLayout invalidateLayout]; 1167 [self.collectionViewLayout invalidateLayout];
1144 } 1168 }
1145 } 1169 }
1146 1170
1147 #pragma mark - SigninPromoViewDelegate 1171 #pragma mark - SigninPromoViewDelegate
1148 1172
1149 - (void)signinPromoViewDidTapSigninWithNewAccount: 1173 - (void)signinPromoViewDidTapSigninWithNewAccount:
1150 (SigninPromoView*)signinPromoView { 1174 (SigninPromoView*)signinPromoView {
1175 [self sendCountTillSigninHistogram];
1151 DCHECK(!_signinPromoViewMediator.defaultIdentity); 1176 DCHECK(!_signinPromoViewMediator.defaultIdentity);
1152 base::RecordAction( 1177 base::RecordAction(
1153 base::UserMetricsAction("Signin_SigninNewAccount_FromSettings")); 1178 base::UserMetricsAction("Signin_SigninNewAccount_FromSettings"));
1154 [self showSignInWithIdentity:nil 1179 [self showSignInWithIdentity:nil
1155 promoAction:signin_metrics::PromoAction:: 1180 promoAction:signin_metrics::PromoAction::
1156 PROMO_ACTION_NEW_ACCOUNT]; 1181 PROMO_ACTION_NEW_ACCOUNT];
1157 } 1182 }
1158 1183
1159 - (void)signinPromoViewDidTapSigninWithDefaultAccount: 1184 - (void)signinPromoViewDidTapSigninWithDefaultAccount:
1160 (SigninPromoView*)signinPromoView { 1185 (SigninPromoView*)signinPromoView {
1186 [self sendCountTillSigninHistogram];
1161 ChromeIdentity* identity = _signinPromoViewMediator.defaultIdentity; 1187 ChromeIdentity* identity = _signinPromoViewMediator.defaultIdentity;
1162 DCHECK(identity); 1188 DCHECK(identity);
1163 base::RecordAction( 1189 base::RecordAction(
1164 base::UserMetricsAction("Signin_SigninWithDefault_FromSettings")); 1190 base::UserMetricsAction("Signin_SigninWithDefault_FromSettings"));
1165 [self showSignInWithIdentity:identity 1191 [self showSignInWithIdentity:identity
1166 promoAction:signin_metrics::PromoAction:: 1192 promoAction:signin_metrics::PromoAction::
1167 PROMO_ACTION_WITH_DEFAULT]; 1193 PROMO_ACTION_WITH_DEFAULT];
1168 } 1194 }
1169 1195
1170 - (void)signinPromoViewDidTapSigninWithOtherAccount: 1196 - (void)signinPromoViewDidTapSigninWithOtherAccount:
1171 (SigninPromoView*)signinPromoView { 1197 (SigninPromoView*)signinPromoView {
1198 [self sendCountTillSigninHistogram];
1172 DCHECK(_signinPromoViewMediator.defaultIdentity); 1199 DCHECK(_signinPromoViewMediator.defaultIdentity);
1173 base::RecordAction( 1200 base::RecordAction(
1174 base::UserMetricsAction("Signin_SigninNotDefault_FromSettings")); 1201 base::UserMetricsAction("Signin_SigninNotDefault_FromSettings"));
1175 [self showSignInWithIdentity:nil 1202 [self showSignInWithIdentity:nil
1176 promoAction:signin_metrics::PromoAction:: 1203 promoAction:signin_metrics::PromoAction::
1177 PROMO_ACTION_NOT_DEFAULT]; 1204 PROMO_ACTION_NOT_DEFAULT];
1178 } 1205 }
1179 1206
1207 #pragma mark - Metrics
1208
1209 - (void)sendCountTillSigninHistogram {
sdefresne 2017/06/26 06:34:35 nit: in your other CL and the histogram.xml file y
jlebel 2017/06/26 19:19:21 Yes, I definitely made a mistake here. Thanks.
1210 _signinStarted = YES;
1211 PrefService* prefs = _browserState->GetPrefs();
1212 int displayedCount =
1213 prefs->GetInteger(prefs::kIosSettingsSigninPromoDisplayedCount);
1214 UMA_HISTOGRAM_COUNTS_100("MobileSignInPromo.SettingsManager.CountTilSignin",
1215 displayedCount);
1216 }
1217
1180 @end 1218 @end
OLDNEW
« no previous file with comments | « ios/chrome/browser/ui/settings/BUILD.gn ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698