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
3 // found in the LICENSE file.
4 
5 #ifndef CHROME_BROWSER_PROFILES_PROFILE_DOWNLOADER_H_
6 #define CHROME_BROWSER_PROFILES_PROFILE_DOWNLOADER_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/gtest_prod_util.h"
12 #include "base/scoped_observer.h"
13 #include "base/sequence_checker.h"
14 #include "base/strings/string16.h"
15 #include "chrome/browser/image_decoder/image_decoder.h"
16 #include "components/signin/public/identity_manager/account_info.h"
17 #include "components/signin/public/identity_manager/identity_manager.h"
18 #include "services/network/public/cpp/simple_url_loader.h"
19 #include "services/network/public/mojom/url_loader_factory.mojom.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 
22 namespace signin {
23 class AccessTokenFetcher;
24 struct AccessTokenInfo;
25 }  // namespace signin
26 
27 class ProfileDownloaderDelegate;
28 
29 // Downloads user profile information. The profile picture is decoded in a
30 // sandboxed process.
31 class ProfileDownloader : public ImageDecoder::ImageRequest,
32                           public signin::IdentityManager::Observer {
33  public:
34   enum PictureStatus {
35     PICTURE_SUCCESS,
36     PICTURE_FAILED,
37     PICTURE_DEFAULT,
38     PICTURE_CACHED,
39   };
40 
41   explicit ProfileDownloader(ProfileDownloaderDelegate* delegate);
42   ProfileDownloader(const ProfileDownloader&) = delete;
43   ProfileDownloader& operator=(const ProfileDownloader&) = delete;
44   ~ProfileDownloader() override;
45 
46   // Starts downloading profile information if the necessary authorization token
47   // is ready. If not, subscribes to token service and starts fetching if the
48   // token is available. Should not be called more than once.
49   virtual void Start();
50 
51   // Starts downloading profile information if the necessary authorization token
52   // is ready. If not, subscribes to token service and starts fetching if the
53   // token is available. Should not be called more than once.
54   virtual void StartForAccount(const CoreAccountId& account_id);
55 
56   // On successful download this returns the hosted domain of the user.
57   virtual base::string16 GetProfileHostedDomain() const;
58 
59   // On successful download this returns the full name of the user. For example
60   // "Pat Smith".
61   virtual base::string16 GetProfileFullName() const;
62 
63   // On successful download this returns the given name of the user. For example
64   // if the name is "Pat Smith", the given name is "Pat".
65   virtual base::string16 GetProfileGivenName() const;
66 
67   // On successful download this returns G+ locale preference of the user.
68   virtual std::string GetProfileLocale() const;
69 
70   // On successful download this returns the profile picture of the user.
71   // For users with no profile picture set (that is, they have the default
72   // profile picture) this will return an Null bitmap.
73   virtual SkBitmap GetProfilePicture() const;
74 
75   // Gets the profile picture status.
76   virtual PictureStatus GetProfilePictureStatus() const;
77 
78   // Gets the URL for the profile picture. This can be cached so that the same
79   // picture is not downloaded multiple times. This value should only be used
80   // when the picture status is PICTURE_SUCCESS.
81   virtual std::string GetProfilePictureURL() const;
82 
83  private:
84   friend class ProfileDownloaderTest;
85   FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest, AccountInfoReady);
86   FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest, AccountInfoNotReady);
87   FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest,
88                            AccountInfoNoPictureDoesNotCrash);
89   FRIEND_TEST_ALL_PREFIXES(ProfileDownloaderTest,
90                            AccountInfoInvalidPictureURLDoesNotCrash);
91 
92   void FetchImageData();
93 
94   void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);
95 
96   // Overridden from ImageDecoder::ImageRequest:
97   void OnImageDecoded(const SkBitmap& decoded_image) override;
98   void OnDecodeImageFailed() override;
99 
100   // Overridden from signin::IdentityManager::Observer:
101   void OnExtendedAccountInfoUpdated(const AccountInfo& info) override;
102 
103   // Callback for AccessTokenFetcher.
104   void OnAccessTokenFetchComplete(GoogleServiceAuthError error,
105                                   signin::AccessTokenInfo access_token_info);
106 
107   // Issues the first request to get user profile image.
108   void StartFetchingImage();
109 
110   // Gets the authorization header.
111   const char* GetAuthorizationHeader() const;
112 
113   // Starts fetching OAuth2 access token. This is needed before the GAIA info
114   // can be downloaded.
115   void StartFetchingOAuth2AccessToken();
116 
117   SEQUENCE_CHECKER(sequence_checker_);
118 
119   ProfileDownloaderDelegate* delegate_;
120   CoreAccountId account_id_;
121   std::string auth_token_;
122   std::unique_ptr<network::SimpleURLLoader> simple_loader_;
123   std::unique_ptr<signin::AccessTokenFetcher> oauth2_access_token_fetcher_;
124   AccountInfo account_info_;
125   SkBitmap profile_picture_;
126   PictureStatus picture_status_ = PICTURE_FAILED;
127   signin::IdentityManager* identity_manager_;
128   ScopedObserver<signin::IdentityManager, signin::IdentityManager::Observer>
129       identity_manager_observer_;
130   bool waiting_for_account_info_ = false;
131 };
132 
133 #endif  // CHROME_BROWSER_PROFILES_PROFILE_DOWNLOADER_H_
134