1 // Copyright 2014 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 #include "chrome/browser/android/profiles/profile_downloader_android.h" 6 7 #include "base/android/jni_android.h" 8 #include "base/android/jni_string.h" 9 #include "chrome/browser/browser_process.h" 10 #include "chrome/browser/profiles/profile_android.h" 11 #include "chrome/browser/profiles/profile_avatar_icon_util.h" 12 #include "chrome/browser/profiles/profile_downloader.h" 13 #include "chrome/browser/profiles/profile_downloader_delegate.h" 14 #include "chrome/browser/profiles/profile_manager.h" 15 #include "jni/ProfileDownloader_jni.h" 16 #include "third_party/skia/include/core/SkBitmap.h" 17 #include "ui/gfx/android/java_bitmap.h" 18 #include "ui/gfx/image/image_skia.h" 19 #include "ui/gfx/screen.h" 20 21 namespace { 22 23 // An account fetcher callback. 24 class AccountInfoRetriever : public ProfileDownloaderDelegate { 25 public: 26 explicit AccountInfoRetriever(Profile* profile, 27 const std::string& account_id, 28 const int desired_image_side_pixels) 29 : profile_(profile), 30 account_id_(account_id), 31 desired_image_side_pixels_(desired_image_side_pixels) {} 32 33 void Start() { 34 profile_image_downloader_.reset(new ProfileDownloader(this)); 35 profile_image_downloader_->StartForAccount(account_id_); 36 } 37 38 void Shutdown() { 39 profile_image_downloader_.reset(); 40 delete this; 41 } 42 43 // ProfileDownloaderDelegate implementation: 44 virtual bool NeedsProfilePicture() const OVERRIDE { 45 return desired_image_side_pixels_ > 0; 46 } 47 48 virtual int GetDesiredImageSideLength() const OVERRIDE { 49 return desired_image_side_pixels_; 50 } 51 52 virtual Profile* GetBrowserProfile() OVERRIDE { 53 return profile_; 54 } 55 56 virtual std::string GetCachedPictureURL() const OVERRIDE { 57 return std::string(); 58 } 59 60 virtual void OnProfileDownloadSuccess( 61 ProfileDownloader* downloader) OVERRIDE { 62 ProfileDownloaderAndroid::OnProfileDownloadSuccess( 63 account_id_, 64 downloader->GetProfileFullName(), 65 downloader->GetProfilePicture()); 66 Shutdown(); 67 } 68 69 virtual void OnProfileDownloadFailure( 70 ProfileDownloader* downloader, 71 ProfileDownloaderDelegate::FailureReason reason) OVERRIDE { 72 LOG(ERROR) << "Failed to download the profile information: " << reason; 73 Shutdown(); 74 } 75 76 // The profile image downloader instance. 77 scoped_ptr<ProfileDownloader> profile_image_downloader_; 78 79 // The browser profile associated with this download request. 80 Profile* profile_; 81 82 // The account ID (email address) to be loaded. 83 const std::string account_id_; 84 85 // Desired side length of the profile image (in pixels). 86 const int desired_image_side_pixels_; 87 88 DISALLOW_COPY_AND_ASSIGN(AccountInfoRetriever); 89 }; 90 91 } // namespace 92 93 // static 94 void ProfileDownloaderAndroid::OnProfileDownloadSuccess( 95 const std::string& account_id, 96 const base::string16& full_name, 97 const SkBitmap& bitmap) { 98 JNIEnv* env = base::android::AttachCurrentThread(); 99 ScopedJavaLocalRef<jobject> jbitmap; 100 if (!bitmap.isNull() && bitmap.bytesPerPixel() != 0) 101 jbitmap = gfx::ConvertToJavaBitmap(&bitmap); 102 Java_ProfileDownloader_onProfileDownloadSuccess( 103 env, 104 base::android::ConvertUTF8ToJavaString(env, account_id).obj(), 105 base::android::ConvertUTF16ToJavaString(env, full_name).obj(), 106 jbitmap.obj()); 107 } 108 109 // static 110 jstring GetCachedNameForPrimaryAccount(JNIEnv* env, 111 jclass clazz, 112 jobject jprofile) { 113 Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); 114 ProfileInfoInterface& info = 115 g_browser_process->profile_manager()->GetProfileInfoCache(); 116 const size_t index = info.GetIndexOfProfileWithPath(profile->GetPath()); 117 118 base::string16 name; 119 if (index != std::string::npos) 120 name = info.GetGAIANameOfProfileAtIndex(index); 121 122 return base::android::ConvertUTF16ToJavaString(env, name).Release(); 123 } 124 125 // static 126 jobject GetCachedAvatarForPrimaryAccount(JNIEnv* env, 127 jclass clazz, 128 jobject jprofile) { 129 Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); 130 ProfileInfoInterface& info = 131 g_browser_process->profile_manager()->GetProfileInfoCache(); 132 const size_t index = info.GetIndexOfProfileWithPath(profile->GetPath()); 133 134 ScopedJavaLocalRef<jobject> jbitmap; 135 if (index != std::string::npos) { 136 gfx::Image avatar_image = info.GetAvatarIconOfProfileAtIndex(index); 137 if (!avatar_image.IsEmpty() && 138 avatar_image.Width() > profiles::kAvatarIconWidth && 139 avatar_image.Height() > profiles::kAvatarIconHeight && 140 avatar_image.AsImageSkia().bitmap()) { 141 jbitmap = gfx::ConvertToJavaBitmap(avatar_image.AsImageSkia().bitmap()); 142 } 143 } 144 145 return jbitmap.Release(); 146 } 147 148 // static 149 void StartFetchingAccountInfoFor( 150 JNIEnv* env, 151 jclass clazz, 152 jobject jprofile, 153 jstring jaccount_id, 154 jint image_side_pixels) { 155 Profile* profile = ProfileAndroid::FromProfileAndroid(jprofile); 156 const std::string account_id = 157 base::android::ConvertJavaStringToUTF8(env, jaccount_id); 158 AccountInfoRetriever* retriever = 159 new AccountInfoRetriever(profile, account_id, image_side_pixels); 160 retriever->Start(); 161 } 162 163 // static 164 bool ProfileDownloaderAndroid::Register(JNIEnv* env) { 165 return RegisterNativesImpl(env); 166 } 167