| Index: ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm
|
| diff --git a/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..a1b8c4671a42e60e271da7d67d424cc3cfa2d63d
|
| --- /dev/null
|
| +++ b/ios/chrome/browser/ui/bookmarks/bookmark_promo_controller.mm
|
| @@ -0,0 +1,216 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// 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/bookmarks/bookmark_promo_controller.h"
|
| +
|
| +#include <memory>
|
| +
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/metrics/user_metrics.h"
|
| +#include "components/pref_registry/pref_registry_syncable.h"
|
| +#include "components/prefs/pref_service.h"
|
| +#include "components/signin/core/browser/signin_manager.h"
|
| +#include "google_apis/gaia/google_service_auth_error.h"
|
| +#include "ios/chrome/browser/browser_state/chrome_browser_state.h"
|
| +#include "ios/chrome/browser/pref_names.h"
|
| +#include "ios/chrome/browser/signin/signin_manager_factory.h"
|
| +#import "ios/chrome/browser/ui/commands/generic_chrome_command.h"
|
| +#import "ios/chrome/browser/ui/commands/show_signin_command.h"
|
| +#import "ios/chrome/browser/ui/ui_util.h"
|
| +
|
| +namespace {
|
| +// Enum is used to record the actions performed by the user on the promo cell.
|
| +// |Stars.PromoActions|.
|
| +enum {
|
| + // Recorded each time the promo cell is presented to the user.
|
| + BOOKMARKS_PROMO_ACTION_DISPLAYED,
|
| + // The user selected the NO THANKS button.
|
| + BOOKMARKS_PROMO_ACTION_DISMISSED,
|
| + // The user selected the SIGN-IN button.
|
| + BOOKMARKS_PROMO_ACTION_COMPLETED,
|
| + // NOTE: Add new promo actions in sources only immediately above this line.
|
| + // Also, make sure the enum list for histogram |Stars.PromoActions| in
|
| + // histograms.xml is updated with any change in here.
|
| + BOOKMARKS_PROMO_ACTION_COUNT
|
| +};
|
| +
|
| +// The histogram used to record user actions performed on the promo cell.
|
| +const char kBookmarksPromoActionsHistogram[] = "Stars.PromoActions";
|
| +
|
| +class SignInObserver;
|
| +} // namespace
|
| +
|
| +@interface BookmarkPromoController () {
|
| + bool _isIncognito;
|
| + ios::ChromeBrowserState* _browserState;
|
| + std::unique_ptr<SignInObserver> _signinObserver;
|
| + bool _promoDisplayedRecorded;
|
| +}
|
| +
|
| +// Records that the promo was displayed. Can be called several times per
|
| +// instance but will effectively record the histogram only once per instance.
|
| +- (void)recordPromoDisplayed;
|
| +
|
| +// SignInObserver Callbacks
|
| +
|
| +// Called when a user signs into Google services such as sync.
|
| +- (void)googleSigninSucceededWithAccountId:(const std::string&)account_id
|
| + username:(const std::string&)username
|
| + password:(const std::string&)password;
|
| +
|
| +// Called when the currently signed-in user for a user has been signed out.
|
| +- (void)googleSignedOutWithAcountId:(const std::string&)account_id
|
| + username:(const std::string&)username;
|
| +
|
| +@end
|
| +
|
| +namespace {
|
| +class SignInObserver : public SigninManagerBase::Observer {
|
| + public:
|
| + SignInObserver(BookmarkPromoController* controller)
|
| + : controller_(controller) {}
|
| +
|
| + void GoogleSigninSucceeded(const std::string& account_id,
|
| + const std::string& username,
|
| + const std::string& password) override {
|
| + [controller_ googleSigninSucceededWithAccountId:account_id
|
| + username:username
|
| + password:password];
|
| + }
|
| +
|
| + void GoogleSignedOut(const std::string& account_id,
|
| + const std::string& username) override {
|
| + [controller_ googleSignedOutWithAcountId:account_id username:username];
|
| + }
|
| +
|
| + private:
|
| + // Weak
|
| + BookmarkPromoController* controller_;
|
| +};
|
| +} // namespace
|
| +
|
| +@implementation BookmarkPromoController
|
| +
|
| +@synthesize delegate = _delegate;
|
| +@synthesize promoState = _promoState;
|
| +
|
| ++ (void)registerBrowserStatePrefs:(user_prefs::PrefRegistrySyncable*)registry {
|
| + registry->RegisterBooleanPref(prefs::kIosBookmarkPromoAlreadySeen, false);
|
| +}
|
| +
|
| +- (instancetype)initWithBrowserState:(ios::ChromeBrowserState*)browserState
|
| + delegate:
|
| + (id<BookmarkPromoControllerDelegate>)delegate {
|
| + self = [super init];
|
| + if (self) {
|
| + _delegate = delegate;
|
| + // Incognito browserState can go away before this class is released, this
|
| + // code avoids keeping a pointer to it.
|
| + _isIncognito = browserState->IsOffTheRecord();
|
| + if (!_isIncognito) {
|
| + _browserState = browserState;
|
| + _signinObserver.reset(new SignInObserver(self));
|
| + SigninManager* signinManager =
|
| + ios::SigninManagerFactory::GetForBrowserState(_browserState);
|
| + signinManager->AddObserver(_signinObserver.get());
|
| + }
|
| + [self updatePromoState];
|
| + }
|
| + return self;
|
| +}
|
| +
|
| +- (void)dealloc {
|
| + if (!_isIncognito) {
|
| + DCHECK(_browserState);
|
| + SigninManager* signinManager =
|
| + ios::SigninManagerFactory::GetForBrowserState(_browserState);
|
| + signinManager->RemoveObserver(_signinObserver.get());
|
| + }
|
| + [super dealloc];
|
| +}
|
| +
|
| +- (void)showSignIn {
|
| + UMA_HISTOGRAM_ENUMERATION(kBookmarksPromoActionsHistogram,
|
| + BOOKMARKS_PROMO_ACTION_COMPLETED,
|
| + BOOKMARKS_PROMO_ACTION_COUNT);
|
| + base::RecordAction(
|
| + base::UserMetricsAction("Signin_Signin_FromBookmarkManager"));
|
| + base::scoped_nsobject<ShowSigninCommand> command([[ShowSigninCommand alloc]
|
| + initWithOperation:AUTHENTICATION_OPERATION_SIGNIN
|
| + signInAccessPoint:signin_metrics::AccessPoint::
|
| + ACCESS_POINT_BOOKMARK_MANAGER]);
|
| + [self chromeExecuteCommand:command];
|
| +}
|
| +
|
| +- (void)hidePromoCell {
|
| + DCHECK(!_isIncognito);
|
| + DCHECK(_browserState);
|
| +
|
| + UMA_HISTOGRAM_ENUMERATION(kBookmarksPromoActionsHistogram,
|
| + BOOKMARKS_PROMO_ACTION_DISMISSED,
|
| + BOOKMARKS_PROMO_ACTION_COUNT);
|
| + PrefService* prefs = _browserState->GetPrefs();
|
| + prefs->SetBoolean(prefs::kIosBookmarkPromoAlreadySeen, true);
|
| + self.promoState = NO;
|
| +}
|
| +
|
| +- (void)setPromoState:(BOOL)promoState {
|
| + if (_promoState != promoState) {
|
| + _promoState = promoState;
|
| + [self.delegate promoStateChanged:promoState];
|
| + }
|
| +}
|
| +
|
| +- (void)updatePromoState {
|
| + self.promoState = NO;
|
| + if (_isIncognito)
|
| + return;
|
| +
|
| + DCHECK(_browserState);
|
| + PrefService* prefs = _browserState->GetPrefs();
|
| + if (!prefs->GetBoolean(prefs::kIosBookmarkPromoAlreadySeen)) {
|
| + SigninManager* signinManager =
|
| + ios::SigninManagerFactory::GetForBrowserState(_browserState);
|
| + self.promoState = !signinManager->IsAuthenticated();
|
| + if (self.promoState)
|
| + [self recordPromoDisplayed];
|
| + }
|
| +}
|
| +
|
| +#pragma mark - Private
|
| +
|
| +- (void)chromeExecuteCommand:(id)sender {
|
| + id delegate = [[UIApplication sharedApplication] delegate];
|
| + if ([delegate respondsToSelector:@selector(chromeExecuteCommand:)])
|
| + [delegate chromeExecuteCommand:sender];
|
| +}
|
| +
|
| +- (void)recordPromoDisplayed {
|
| + if (_promoDisplayedRecorded)
|
| + return;
|
| + _promoDisplayedRecorded = YES;
|
| + UMA_HISTOGRAM_ENUMERATION(kBookmarksPromoActionsHistogram,
|
| + BOOKMARKS_PROMO_ACTION_DISPLAYED,
|
| + BOOKMARKS_PROMO_ACTION_COUNT);
|
| + base::RecordAction(
|
| + base::UserMetricsAction("Signin_Impression_FromBookmarkManager"));
|
| +}
|
| +
|
| +#pragma mark - SignInObserver
|
| +
|
| +// Called when a user signs into Google services such as sync.
|
| +- (void)googleSigninSucceededWithAccountId:(const std::string&)account_id
|
| + username:(const std::string&)username
|
| + password:(const std::string&)password {
|
| + self.promoState = NO;
|
| +}
|
| +
|
| +// Called when the currently signed-in user for a user has been signed out.
|
| +- (void)googleSignedOutWithAcountId:(const std::string&)account_id
|
| + username:(const std::string&)username {
|
| + [self updatePromoState];
|
| +}
|
| +
|
| +@end
|
|
|