Rename GetIconID to GetIconId
[chromium-blink-merge.git] / chrome / browser / android / bookmarks / partner_bookmarks_reader.cc
blob78941931a98d7f7a9829fbaae663ce341c5f43b1
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
3 // found in the LICENSE file.
5 #include "chrome/browser/android/bookmarks/partner_bookmarks_reader.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/logging.h"
10 #include "chrome/browser/android/bookmarks/partner_bookmarks_shim.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/favicon/favicon_service_factory.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_manager.h"
15 #include "components/bookmarks/browser/bookmark_model.h"
16 #include "components/favicon/core/favicon_service.h"
17 #include "components/favicon_base/favicon_types.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "jni/PartnerBookmarksReader_jni.h"
20 #include "third_party/skia/include/core/SkBitmap.h"
21 #include "ui/gfx/codec/png_codec.h"
22 #include "ui/gfx/favicon_size.h"
24 using base::android::AttachCurrentThread;
25 using base::android::CheckException;
26 using base::android::ConvertJavaStringToUTF16;
27 using bookmarks::BookmarkNode;
28 using bookmarks::BookmarkPermanentNode;
29 using content::BrowserThread;
31 namespace {
33 void SetFaviconTask(Profile* profile,
34 const GURL& page_url, const GURL& icon_url,
35 const std::vector<unsigned char>& image_data,
36 favicon_base::IconType icon_type) {
37 DCHECK_CURRENTLY_ON(BrowserThread::UI);
38 scoped_refptr<base::RefCountedMemory> bitmap_data(
39 new base::RefCountedBytes(image_data));
40 gfx::Size pixel_size(gfx::kFaviconSize, gfx::kFaviconSize);
41 favicon::FaviconService* favicon_service =
42 FaviconServiceFactory::GetForProfile(
43 ProfileManager::GetActiveUserProfile(),
44 ServiceAccessType::EXPLICIT_ACCESS);
45 if (!favicon_service)
46 return;
48 favicon_service->MergeFavicon(
49 page_url, page_url, icon_type, bitmap_data, pixel_size);
52 void SetFaviconCallback(Profile* profile,
53 const GURL& page_url, const GURL& icon_url,
54 const std::vector<unsigned char>& image_data,
55 favicon_base::IconType icon_type,
56 base::WaitableEvent* bookmark_added_event) {
57 SetFaviconTask(profile, page_url, icon_url, image_data, icon_type);
58 if (bookmark_added_event)
59 bookmark_added_event->Signal();
62 void PrepareAndSetFavicon(JNIEnv* env, jbyte* icon_bytes, int icon_len,
63 BookmarkNode* node, Profile* profile,
64 favicon_base::IconType icon_type) {
65 SkBitmap icon_bitmap;
66 if (!gfx::PNGCodec::Decode(
67 reinterpret_cast<const unsigned char*>(icon_bytes),
68 icon_len, &icon_bitmap))
69 return;
70 std::vector<unsigned char> image_data;
71 if (!gfx::PNGCodec::EncodeBGRASkBitmap(icon_bitmap, false, &image_data))
72 return;
73 // TODO(aruslan): TODO(tedchoc): Follow up on how to avoid this through js.
74 // Since the favicon URL is used as a key in the history's thumbnail DB,
75 // this gives us a value which does not collide with others.
76 GURL fake_icon_url = node->url();
77 if (BrowserThread::CurrentlyOn(BrowserThread::UI)) {
78 SetFaviconTask(profile,
79 node->url(), fake_icon_url,
80 image_data, icon_type);
81 } else {
82 base::WaitableEvent event(false, false);
83 BrowserThread::PostTask(
84 BrowserThread::UI,
85 FROM_HERE,
86 base::Bind(&SetFaviconCallback,
87 profile, node->url(), fake_icon_url,
88 image_data, icon_type, &event));
89 // TODO(aruslan): http://b/6397072 If possible - avoid using favicon service
90 event.Wait();
94 const BookmarkNode* GetNodeByID(const BookmarkNode* parent, int64 id) {
95 if (parent->id() == id)
96 return parent;
97 for (int i= 0, child_count = parent->child_count(); i < child_count; ++i) {
98 const BookmarkNode* result = GetNodeByID(parent->GetChild(i), id);
99 if (result)
100 return result;
102 return NULL;
105 } // namespace
107 PartnerBookmarksReader::PartnerBookmarksReader(
108 PartnerBookmarksShim* partner_bookmarks_shim,
109 Profile* profile)
110 : partner_bookmarks_shim_(partner_bookmarks_shim),
111 profile_(profile),
112 wip_next_available_id_(0) {
115 PartnerBookmarksReader::~PartnerBookmarksReader() {}
117 void PartnerBookmarksReader::PartnerBookmarksCreationComplete(JNIEnv*,
118 jobject) {
119 DCHECK_CURRENTLY_ON(BrowserThread::UI);
120 partner_bookmarks_shim_->SetPartnerBookmarksRoot(
121 wip_partner_bookmarks_root_.release());
122 wip_next_available_id_ = 0;
125 void PartnerBookmarksReader::Destroy(JNIEnv* env, jobject obj) {
126 delete this;
129 void PartnerBookmarksReader::Reset(JNIEnv* env, jobject obj) {
130 DCHECK_CURRENTLY_ON(BrowserThread::UI);
131 wip_partner_bookmarks_root_.reset();
132 wip_next_available_id_ = 0;
135 jlong PartnerBookmarksReader::AddPartnerBookmark(JNIEnv* env,
136 jobject obj,
137 jstring jurl,
138 jstring jtitle,
139 jboolean is_folder,
140 jlong parent_id,
141 jbyteArray favicon,
142 jbyteArray touchicon) {
143 base::string16 url;
144 base::string16 title;
145 if (jurl)
146 url = ConvertJavaStringToUTF16(env, jurl);
147 if (jtitle)
148 title = ConvertJavaStringToUTF16(env, jtitle);
150 BookmarkNode* node = NULL;
151 if (wip_partner_bookmarks_root_.get()) {
152 node = new BookmarkNode(wip_next_available_id_++, GURL(url));
153 node->set_type(is_folder ? BookmarkNode::FOLDER : BookmarkNode::URL);
154 node->SetTitle(title);
156 // Handle favicon and touchicon
157 if (profile_ != NULL && (favicon != NULL || touchicon != NULL)) {
158 jbyteArray icon = (touchicon != NULL) ? touchicon : favicon;
159 const favicon_base::IconType icon_type =
160 touchicon ? favicon_base::TOUCH_ICON : favicon_base::FAVICON;
161 const int icon_len = env->GetArrayLength(icon);
162 jbyte* icon_bytes = env->GetByteArrayElements(icon, NULL);
163 if (icon_bytes)
164 PrepareAndSetFavicon(env, icon_bytes, icon_len,
165 node, profile_, icon_type);
166 env->ReleaseByteArrayElements(icon, icon_bytes, JNI_ABORT);
169 const BookmarkNode* parent =
170 GetNodeByID(wip_partner_bookmarks_root_.get(), parent_id);
171 if (!parent) {
172 LOG(WARNING) << "partner_bookmarks_shim: invalid/unknown parent_id="
173 << parent_id << ": adding to the root";
174 parent = wip_partner_bookmarks_root_.get();
176 const_cast<BookmarkNode*>(parent)->Add(node, parent->child_count());
177 } else {
178 node = new BookmarkPermanentNode(wip_next_available_id_++);
179 node->SetTitle(title);
180 wip_partner_bookmarks_root_.reset(node);
182 return node->id();
185 // static
186 static void DisablePartnerBookmarksEditing(JNIEnv* env, jclass clazz) {
187 PartnerBookmarksShim::DisablePartnerBookmarksEditing();
190 // static
191 bool PartnerBookmarksReader::RegisterPartnerBookmarksReader(JNIEnv* env) {
192 return RegisterNativesImpl(env);
195 // ----------------------------------------------------------------
197 static jlong Init(JNIEnv* env, jobject obj) {
198 Profile* profile = ProfileManager::GetActiveUserProfile();
199 PartnerBookmarksShim* partner_bookmarks_shim =
200 PartnerBookmarksShim::BuildForBrowserContext(profile);
201 PartnerBookmarksReader* reader = new PartnerBookmarksReader(
202 partner_bookmarks_shim, profile);
203 return reinterpret_cast<intptr_t>(reader);