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

Side by Side Diff: chrome/browser/profiles/gaia_info_update_service_unittest.cc

Issue 1794353003: Refactor ProfileInfoCache in c/b/profiles (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 #include "chrome/browser/profiles/gaia_info_update_service.h" 5 #include "chrome/browser/profiles/gaia_info_update_service.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <string> 9 #include <string>
10 10
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "build/build_config.h" 12 #include "build/build_config.h"
13 #include "chrome/browser/browser_process.h" 13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/profiles/profile_attributes_entry.h"
15 #include "chrome/browser/profiles/profile_attributes_storage.h"
14 #include "chrome/browser/profiles/profile_downloader.h" 16 #include "chrome/browser/profiles/profile_downloader.h"
15 #include "chrome/browser/profiles/profile_info_cache.h"
16 #include "chrome/browser/profiles/profile_info_cache_unittest.h" 17 #include "chrome/browser/profiles/profile_info_cache_unittest.h"
17 #include "chrome/browser/profiles/profiles_state.h" 18 #include "chrome/browser/profiles/profiles_state.h"
18 #include "chrome/browser/signin/account_tracker_service_factory.h" 19 #include "chrome/browser/signin/account_tracker_service_factory.h"
19 #include "chrome/browser/signin/chrome_signin_client_factory.h" 20 #include "chrome/browser/signin/chrome_signin_client_factory.h"
20 #include "chrome/browser/signin/signin_manager_factory.h" 21 #include "chrome/browser/signin/signin_manager_factory.h"
21 #include "chrome/browser/signin/test_signin_client_builder.h" 22 #include "chrome/browser/signin/test_signin_client_builder.h"
22 #include "chrome/common/pref_names.h" 23 #include "chrome/common/pref_names.h"
23 #include "chrome/test/base/testing_browser_process.h" 24 #include "chrome/test/base/testing_browser_process.h"
24 #include "chrome/test/base/testing_profile.h" 25 #include "chrome/test/base/testing_profile.h"
25 #include "chrome/test/base/testing_profile_manager.h" 26 #include "chrome/test/base/testing_profile_manager.h"
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
59 explicit GAIAInfoUpdateServiceMock(Profile* profile) 60 explicit GAIAInfoUpdateServiceMock(Profile* profile)
60 : GAIAInfoUpdateService(profile) { 61 : GAIAInfoUpdateService(profile) {
61 } 62 }
62 63
63 virtual ~GAIAInfoUpdateServiceMock() { 64 virtual ~GAIAInfoUpdateServiceMock() {
64 } 65 }
65 66
66 MOCK_METHOD0(Update, void()); 67 MOCK_METHOD0(Update, void());
67 }; 68 };
68 69
69 class GAIAInfoUpdateServiceTest : public ProfileInfoCacheTest { 70 class GAIAInfoUpdateServiceTest : public ProfileInfoCacheTest {
lwchkg 2016/03/14 15:49:10 It is a TODO to remove ProfileInfoCacheTest from t
Mike Lerman 2016/03/18 17:10:44 sure
lwchkg 2016/03/19 18:48:45 Acknowledged.
70 protected: 71 protected:
71 GAIAInfoUpdateServiceTest() : profile_(NULL) { 72 GAIAInfoUpdateServiceTest() : profile_(NULL) {
72 } 73 }
73 74
74 Profile* profile() { 75 Profile* profile() {
75 if (!profile_) 76 if (!profile_)
76 profile_ = CreateProfile("Person 1"); 77 profile_ = CreateProfile("Person 1");
77 return profile_; 78 return profile_;
78 } 79 }
79 80
81 ProfileAttributesStorage* storage() {
82 return testing_profile_manager_.profile_attributes_storage();
83 }
84
80 NiceMock<GAIAInfoUpdateServiceMock>* service() { return service_.get(); } 85 NiceMock<GAIAInfoUpdateServiceMock>* service() { return service_.get(); }
81 NiceMock<ProfileDownloaderMock>* downloader() { return downloader_.get(); } 86 NiceMock<ProfileDownloaderMock>* downloader() { return downloader_.get(); }
82 87
83 Profile* CreateProfile(const std::string& name) { 88 Profile* CreateProfile(const std::string& name) {
84 TestingProfile::TestingFactories testing_factories; 89 TestingProfile::TestingFactories testing_factories;
85 testing_factories.push_back(std::make_pair( 90 testing_factories.push_back(std::make_pair(
86 ChromeSigninClientFactory::GetInstance(), 91 ChromeSigninClientFactory::GetInstance(),
87 signin::BuildTestSigninClient)); 92 signin::BuildTestSigninClient));
88 Profile* profile = testing_profile_manager_.CreateTestingProfile( 93 Profile* profile = testing_profile_manager_.CreateTestingProfile(
89 name, scoped_ptr<syncable_prefs::PrefServiceSyncable>(), 94 name, scoped_ptr<syncable_prefs::PrefServiceSyncable>(),
90 base::UTF8ToUTF16(name), 0, std::string(), testing_factories); 95 base::UTF8ToUTF16(name), 0, std::string(), testing_factories);
91 // The testing manager sets the profile name manually, which counts as 96 // The testing manager sets the profile name manually, which counts as
92 // a user-customized profile name. Reset this to match the default name 97 // a user-customized profile name. Reset this to match the default name
93 // we are actually using. 98 // we are actually using.
94 size_t index = GetCache()->GetIndexOfProfileWithPath(profile->GetPath()); 99 ProfileAttributesEntry* entry = nullptr;
95 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index, true); 100 // TODO(anthonyvd) : refactor the function so the following assertion can be
101 // changed to ASSERT_TRUE.
102 DCHECK(storage()->GetProfileAttributesWithPath(profile->GetPath(), &entry));
103 entry->SetIsUsingDefaultName(true);
96 return profile; 104 return profile;
97 } 105 }
98 106
99 static std::string GivenName(const std::string& id) {
100 return id + "first";
101 }
102 static std::string FullName(const std::string& id) {
103 return GivenName(id) + " " + id + "last";
104 }
105 static base::string16 GivenName16(const std::string& id) {
106 return base::UTF8ToUTF16(GivenName(id));
107 }
108 static base::string16 FullName16(const std::string& id) {
109 return base::UTF8ToUTF16(FullName(id));
110 }
111
112 void ProfileDownloadSuccess( 107 void ProfileDownloadSuccess(
113 const base::string16& full_name, 108 const base::string16& full_name,
114 const base::string16& given_name, 109 const base::string16& given_name,
115 const gfx::Image& image, 110 const gfx::Image& image,
116 const std::string& url, 111 const std::string& url,
117 const base::string16& hosted_domain) { 112 const base::string16& hosted_domain) {
118 EXPECT_CALL(*downloader(), GetProfileFullName()). 113 EXPECT_CALL(*downloader(), GetProfileFullName()).
119 WillOnce(Return(full_name)); 114 WillOnce(Return(full_name));
120 EXPECT_CALL(*downloader(), GetProfileGivenName()). 115 EXPECT_CALL(*downloader(), GetProfileGivenName()).
121 WillOnce(Return(given_name)); 116 WillOnce(Return(given_name));
122 const SkBitmap* bmp = image.ToSkBitmap(); 117 const SkBitmap* bmp = image.ToSkBitmap();
123 EXPECT_CALL(*downloader(), GetProfilePicture()).WillOnce(Return(*bmp)); 118 EXPECT_CALL(*downloader(), GetProfilePicture()).WillOnce(Return(*bmp));
124 EXPECT_CALL(*downloader(), GetProfilePictureStatus()). 119 EXPECT_CALL(*downloader(), GetProfilePictureStatus()).
125 WillOnce(Return(ProfileDownloader::PICTURE_SUCCESS)); 120 WillOnce(Return(ProfileDownloader::PICTURE_SUCCESS));
126 EXPECT_CALL(*downloader(), GetProfilePictureURL()).WillOnce(Return(url)); 121 EXPECT_CALL(*downloader(), GetProfilePictureURL()).WillOnce(Return(url));
127 EXPECT_CALL(*downloader(), GetProfileHostedDomain()). 122 EXPECT_CALL(*downloader(), GetProfileHostedDomain()).
128 WillOnce(Return(hosted_domain)); 123 WillOnce(Return(hosted_domain));
129 124
130 service()->OnProfileDownloadSuccess(downloader()); 125 service()->OnProfileDownloadSuccess(downloader());
131 } 126 }
132 127
133 void RenameProfile(const base::string16& full_name,
134 const base::string16& given_name) {
135 gfx::Image image = gfx::test::CreateImage(256, 256);
136 std::string url("foo.com");
137 ProfileDownloadSuccess(full_name, given_name, image, url, base::string16());
138
139 // Make sure the right profile was updated correctly.
140 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
141 EXPECT_EQ(full_name, GetCache()->GetGAIANameOfProfileAtIndex(index));
142 EXPECT_EQ(given_name, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index));
143 }
144
145 private: 128 private:
146 void SetUp() override; 129 void SetUp() override;
147 void TearDown() override; 130 void TearDown() override;
148 131
149 Profile* profile_; 132 Profile* profile_;
150 scoped_ptr<NiceMock<GAIAInfoUpdateServiceMock> > service_; 133 scoped_ptr<NiceMock<GAIAInfoUpdateServiceMock> > service_;
151 scoped_ptr<NiceMock<ProfileDownloaderMock> > downloader_; 134 scoped_ptr<NiceMock<ProfileDownloaderMock> > downloader_;
152 }; 135 };
153 136
154 void GAIAInfoUpdateServiceTest::SetUp() { 137 void GAIAInfoUpdateServiceTest::SetUp() {
(...skipping 18 matching lines...) Expand all
173 GetString(prefs::kGoogleServicesHostedDomain)); 156 GetString(prefs::kGoogleServicesHostedDomain));
174 157
175 base::string16 name = base::ASCIIToUTF16("Pat Smith"); 158 base::string16 name = base::ASCIIToUTF16("Pat Smith");
176 base::string16 given_name = base::ASCIIToUTF16("Pat"); 159 base::string16 given_name = base::ASCIIToUTF16("Pat");
177 gfx::Image image = gfx::test::CreateImage(256, 256); 160 gfx::Image image = gfx::test::CreateImage(256, 256);
178 std::string url("foo.com"); 161 std::string url("foo.com");
179 base::string16 hosted_domain(base::ASCIIToUTF16("")); 162 base::string16 hosted_domain(base::ASCIIToUTF16(""));
180 ProfileDownloadSuccess(name, given_name, image, url, hosted_domain); 163 ProfileDownloadSuccess(name, given_name, image, url, hosted_domain);
181 164
182 // On success the GAIA info should be updated. 165 // On success the GAIA info should be updated.
183 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 166 ProfileAttributesEntry* entry;
184 EXPECT_EQ(name, GetCache()->GetGAIANameOfProfileAtIndex(index)); 167 ASSERT_TRUE(storage()->GetProfileAttributesWithPath(profile()->GetPath(),
185 EXPECT_EQ(given_name, GetCache()->GetGAIAGivenNameOfProfileAtIndex(index)); 168 &entry));
186 EXPECT_TRUE(gfx::test::AreImagesEqual( 169 EXPECT_EQ(name, entry->GetGAIAName());
187 image, *GetCache()->GetGAIAPictureOfProfileAtIndex(index))); 170 EXPECT_EQ(given_name, entry->GetGAIAGivenName());
171 EXPECT_TRUE(gfx::test::AreImagesEqual(image, *entry->GetGAIAPicture()));
188 EXPECT_EQ(url, service()->GetCachedPictureURL()); 172 EXPECT_EQ(url, service()->GetCachedPictureURL());
189 EXPECT_EQ(Profile::kNoHostedDomainFound, profile()->GetPrefs()-> 173 EXPECT_EQ(Profile::kNoHostedDomainFound, profile()->GetPrefs()->
190 GetString(prefs::kGoogleServicesHostedDomain)); 174 GetString(prefs::kGoogleServicesHostedDomain));
191 } 175 }
192 176
193 TEST_F(GAIAInfoUpdateServiceTest, DownloadFailure) { 177 TEST_F(GAIAInfoUpdateServiceTest, DownloadFailure) {
194 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()); 178 ProfileAttributesEntry* entry;
195 base::string16 old_name = GetCache()->GetNameOfProfileAtIndex(index); 179 ASSERT_TRUE(storage()->GetProfileAttributesWithPath(profile()->GetPath(),
196 gfx::Image old_image = GetCache()->GetAvatarIconOfProfileAtIndex(index); 180 &entry));
181 base::string16 old_name = entry->GetName();
182 gfx::Image old_image = entry->GetAvatarIcon();
197 183
198 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 184 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
199 185
200 service()->OnProfileDownloadFailure(downloader(), 186 service()->OnProfileDownloadFailure(downloader(),
201 ProfileDownloaderDelegate::SERVICE_ERROR); 187 ProfileDownloaderDelegate::SERVICE_ERROR);
202 188
203 // On failure nothing should be updated. 189 // On failure nothing should be updated.
204 EXPECT_EQ(old_name, GetCache()->GetNameOfProfileAtIndex(index)); 190 EXPECT_EQ(old_name, entry->GetName());
205 EXPECT_EQ(base::string16(), GetCache()->GetGAIANameOfProfileAtIndex(index)); 191 EXPECT_EQ(base::string16(), entry->GetGAIAName());
206 EXPECT_EQ(base::string16(), 192 EXPECT_EQ(base::string16(), entry->GetGAIAGivenName());
207 GetCache()->GetGAIAGivenNameOfProfileAtIndex(index)); 193 EXPECT_TRUE(gfx::test::AreImagesEqual(old_image, entry->GetAvatarIcon()));
208 EXPECT_TRUE(gfx::test::AreImagesEqual( 194 EXPECT_EQ(nullptr, entry->GetGAIAPicture());
209 old_image, GetCache()->GetAvatarIconOfProfileAtIndex(index)));
210 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(index));
211 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 195 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
212 EXPECT_EQ(std::string(), 196 EXPECT_EQ(std::string(),
213 profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain)); 197 profile()->GetPrefs()->GetString(prefs::kGoogleServicesHostedDomain));
214 } 198 }
215 199
216 TEST_F(GAIAInfoUpdateServiceTest, ProfileLockEnabledForWhitelist) { 200 TEST_F(GAIAInfoUpdateServiceTest, ProfileLockEnabledForWhitelist) {
217 // No URL should be cached yet. 201 // No URL should be cached yet.
218 EXPECT_EQ(std::string(), service()->GetCachedPictureURL()); 202 EXPECT_EQ(std::string(), service()->GetCachedPictureURL());
219 203
220 base::string16 name = base::ASCIIToUTF16("Pat Smith"); 204 base::string16 name = base::ASCIIToUTF16("Pat Smith");
221 base::string16 given_name = base::ASCIIToUTF16("Pat"); 205 base::string16 given_name = base::ASCIIToUTF16("Pat");
222 gfx::Image image = gfx::test::CreateImage(256, 256); 206 gfx::Image image = gfx::test::CreateImage(256, 256);
223 std::string url("foo.com"); 207 std::string url("foo.com");
224 base::string16 hosted_domain(base::ASCIIToUTF16("google.com")); 208 base::string16 hosted_domain(base::ASCIIToUTF16("google.com"));
225 ProfileDownloadSuccess(name, given_name, image, url, hosted_domain); 209 ProfileDownloadSuccess(name, given_name, image, url, hosted_domain);
226 210
227 EXPECT_EQ("google.com", profile()->GetPrefs()-> 211 EXPECT_EQ("google.com", profile()->GetPrefs()->
228 GetString(prefs::kGoogleServicesHostedDomain)); 212 GetString(prefs::kGoogleServicesHostedDomain));
229 } 213 }
230 214
231 TEST_F(GAIAInfoUpdateServiceTest, HandlesProfileReordering) {
Mike Lerman 2016/03/18 17:10:44 I'd almost prefer to leave this in until we've ful
lwchkg 2016/03/19 18:48:46 Acknowledged.
232 size_t index = GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
233 GetCache()->SetNameOfProfileAtIndex(index, FullName16("B"));
234 GetCache()->SetProfileIsUsingDefaultNameAtIndex(index, true);
235
236 CreateProfile(FullName("A"));
237 CreateProfile(FullName("C"));
238 CreateProfile(FullName("E"));
239
240 size_t index_before =
241 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath());
242
243 // Rename our profile.
244 RenameProfile(FullName16("D"), GivenName16("D"));
245 // Profiles should have been reordered in the cache.
246 EXPECT_NE(index_before,
247 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
248 // Rename the profile back to the original name, it should go back to its
249 // original position.
250 RenameProfile(FullName16("B"), GivenName16("B"));
251 EXPECT_EQ(index_before,
252 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
253
254 // Rename only the given name of our profile.
255 RenameProfile(FullName16("B"), GivenName16("D"));
256 // Rename the profile back to the original name, it should go back to its
257 // original position.
258 RenameProfile(FullName16("B"), GivenName16("B"));
259 EXPECT_EQ(index_before,
260 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
261
262 // Rename only the full name of our profile.
263 RenameProfile(FullName16("D"), GivenName16("B"));
264 // Rename the profile back to the original name, it should go back to its
265 // original position.
266 RenameProfile(FullName16("B"), GivenName16("B"));
267 EXPECT_EQ(index_before,
268 GetCache()->GetIndexOfProfileWithPath(profile()->GetPath()));
269 }
270
271 TEST_F(GAIAInfoUpdateServiceTest, ShouldUseGAIAProfileInfo) { 215 TEST_F(GAIAInfoUpdateServiceTest, ShouldUseGAIAProfileInfo) {
272 #if defined(OS_CHROMEOS) 216 #if defined(OS_CHROMEOS)
273 // This feature should never be enabled on ChromeOS. 217 // This feature should never be enabled on ChromeOS.
274 EXPECT_FALSE(GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(profile())); 218 EXPECT_FALSE(GAIAInfoUpdateService::ShouldUseGAIAProfileInfo(profile()));
275 #endif 219 #endif
276 } 220 }
277 221
278 TEST_F(GAIAInfoUpdateServiceTest, ScheduleUpdate) { 222 TEST_F(GAIAInfoUpdateServiceTest, ScheduleUpdate) {
279 EXPECT_TRUE(service()->timer_.IsRunning()); 223 EXPECT_TRUE(service()->timer_.IsRunning());
280 service()->timer_.Stop(); 224 service()->timer_.Stop();
281 EXPECT_FALSE(service()->timer_.IsRunning()); 225 EXPECT_FALSE(service()->timer_.IsRunning());
282 service()->ScheduleNextUpdate(); 226 service()->ScheduleNextUpdate();
283 EXPECT_TRUE(service()->timer_.IsRunning()); 227 EXPECT_TRUE(service()->timer_.IsRunning());
284 } 228 }
285 229
286 #if !defined(OS_CHROMEOS) 230 #if !defined(OS_CHROMEOS)
287 231
288 TEST_F(GAIAInfoUpdateServiceTest, LogOut) { 232 TEST_F(GAIAInfoUpdateServiceTest, LogOut) {
289 SigninManager* signin_manager = 233 SigninManager* signin_manager =
290 SigninManagerFactory::GetForProfile(profile()); 234 SigninManagerFactory::GetForProfile(profile());
291 signin_manager->SetAuthenticatedAccountInfo("gaia_id", "pat@example.com"); 235 signin_manager->SetAuthenticatedAccountInfo("gaia_id", "pat@example.com");
292 base::string16 gaia_name = base::UTF8ToUTF16("Pat Foo"); 236 base::string16 gaia_name = base::UTF8ToUTF16("Pat Foo");
293 GetCache()->SetGAIANameOfProfileAtIndex(0, gaia_name); 237
238 ASSERT_EQ(1u, storage()->GetNumberOfProfiles());
239 ProfileAttributesEntry* entry = storage()->GetAllProfilesAttributes().front();
240 entry->SetGAIAName(gaia_name);
294 gfx::Image gaia_picture = gfx::test::CreateImage(256, 256); 241 gfx::Image gaia_picture = gfx::test::CreateImage(256, 256);
295 GetCache()->SetGAIAPictureOfProfileAtIndex(0, &gaia_picture); 242 entry->SetGAIAPicture(&gaia_picture);
296 243
297 // Set a fake picture URL. 244 // Set a fake picture URL.
298 profile()->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL, 245 profile()->GetPrefs()->SetString(prefs::kProfileGAIAInfoPictureURL,
299 "example.com"); 246 "example.com");
300 247
301 EXPECT_FALSE(service()->GetCachedPictureURL().empty()); 248 EXPECT_FALSE(service()->GetCachedPictureURL().empty());
302 249
303 // Log out. 250 // Log out.
304 signin_manager->SignOut(signin_metrics::SIGNOUT_TEST, 251 signin_manager->SignOut(signin_metrics::SIGNOUT_TEST,
305 signin_metrics::SignoutDelete::IGNORE_METRIC); 252 signin_metrics::SignoutDelete::IGNORE_METRIC);
306 // Verify that the GAIA name and picture, and picture URL are unset. 253 // Verify that the GAIA name and picture, and picture URL are unset.
307 EXPECT_TRUE(GetCache()->GetGAIANameOfProfileAtIndex(0).empty()); 254 EXPECT_TRUE(entry->GetGAIAName().empty());
308 EXPECT_EQ(NULL, GetCache()->GetGAIAPictureOfProfileAtIndex(0)); 255 EXPECT_EQ(nullptr, entry->GetGAIAPicture());
309 EXPECT_TRUE(service()->GetCachedPictureURL().empty()); 256 EXPECT_TRUE(service()->GetCachedPictureURL().empty());
310 } 257 }
311 258
312 TEST_F(GAIAInfoUpdateServiceTest, LogIn) { 259 TEST_F(GAIAInfoUpdateServiceTest, LogIn) {
313 // Log in. 260 // Log in.
314 EXPECT_CALL(*service(), Update()); 261 EXPECT_CALL(*service(), Update());
315 AccountTrackerServiceFactory::GetForProfile(profile()) 262 AccountTrackerServiceFactory::GetForProfile(profile())
316 ->SeedAccountInfo("gaia_id", "pat@example.com"); 263 ->SeedAccountInfo("gaia_id", "pat@example.com");
317 SigninManager* signin_manager = 264 SigninManager* signin_manager =
318 SigninManagerFactory::GetForProfile(profile()); 265 SigninManagerFactory::GetForProfile(profile());
319 signin_manager->OnExternalSigninCompleted("pat@example.com"); 266 signin_manager->OnExternalSigninCompleted("pat@example.com");
320 } 267 }
321 268
322 #endif 269 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698