15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/android/provider/chrome_browser_provider.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include <cmath>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_android.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_array.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/jni_string.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted_memory.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h"
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/android/provider/blocking_ui_thread_async_request.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/android/provider/bookmark_model_observer_task.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/android/provider/run_on_ui_thread_blocking.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/bookmarks/bookmark_model_factory.h"
23f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/bookmarks/chrome_bookmark_client.h"
24f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)#include "chrome/browser/bookmarks/chrome_bookmark_client_factory.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/browser_process.h"
267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_service_factory.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/sqlite_cursor.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/top_sites.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/search_engines/template_url_service_factory.h"
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_model.h"
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/bookmarks/browser/bookmark_utils.h"
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/history/core/android/android_history_types.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url.h"
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/search_engines/template_url_service.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_thread.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jni/ChromeBrowserProvider_jni.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/layout.h"
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/favicon_size.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::AttachCurrentThread;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::CheckException;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ClearException;
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ConvertJavaStringToUTF16;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ConvertJavaStringToUTF8;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ConvertUTF8ToJavaString;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ConvertUTF16ToJavaString;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::GetClass;
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::MethodID;
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::JavaRef;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ScopedJavaGlobalRef;
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::android::ScopedJavaLocalRef;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::BrowserThread;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// After refactoring the following class hierarchy has been created in order
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to avoid repeating code again for the same basic kind of tasks, to enforce
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the correct thread usage and to prevent known race conditions and deadlocks.
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - RunOnUIThreadBlocking: auxiliary class to run methods in the UI thread
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   blocking the current one until finished. Because of the provider threading
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   expectations this cannot be used from the UI thread.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - BookmarkModelTask: base class for all tasks that operate in any way with
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   the bookmark model. This class ensures that the model is loaded and
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   prevents possible deadlocks. Derived classes should make use of
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   RunOnUIThreadBlocking to perform any manipulation of the bookmark model in
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   the UI thread. The Run method of these tasks cannot be invoked directly
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   from the UI thread, but RunOnUIThread can be safely used from the UI
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   thread code of other BookmarkModelTasks.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - AsyncServiceRequest: base class for any asynchronous requests made to a
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Chromium service that require to block the current thread until completed.
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Derived classes should make use of RunAsyncRequestOnUIThreadBlocking to
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   post their requests in the UI thread and return the results synchronously.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   All derived classes MUST ALWAYS call RequestCompleted when receiving the
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   request response. These tasks cannot be invoked from the UI thread.
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - FaviconServiceTask: base class for asynchronous requests that make use of
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   Chromium's favicon service. See AsyncServiceRequest for more details.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - HistoryProviderTask: base class for asynchronous requests that make use of
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   AndroidHistoryProviderService. See AsyncServiceRequest for mode details.
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// - SearchTermTask: base class for asynchronous requests that involve the
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   search term API. Works in the same way as HistoryProviderTask.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDefaultUrlScheme[] = "http://";
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kInvalidContentProviderId = 0;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int64 kInvalidBookmarkId = -1;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Java-related utility methods ------------- //
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Convert a BookmarkNode, |node|, to the java representation of a bookmark node
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// stored in |*jnode|. Parent node information is optional.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ConvertBookmarkNode(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* node,
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const JavaRef<jobject>& parent_node,
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedJavaGlobalRef<jobject>* jnode) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(jnode);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!node)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> url;
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (node->is_url())
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url.Reset(ConvertUTF8ToJavaString(env, node->url().spec()));
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jstring> title(
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertUTF16ToJavaString(env, node->GetTitle()));
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jnode->Reset(
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Java_BookmarkNode_create(
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          env, node->id(), (jint) node->type(), title.obj(), url.obj(),
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          parent_node.obj()));
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jlong ConvertJLongObjectToPrimitive(JNIEnv* env, jobject long_obj) {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jclass> jlong_clazz = GetClass(env, "java/lang/Long");
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jmethodID long_value = MethodID::Get<MethodID::TYPE_INSTANCE>(
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env, jlong_clazz.obj(), "longValue", "()J");
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return env->CallLongMethod(long_obj, long_value, NULL);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jboolean ConvertJBooleanObjectToPrimitive(JNIEnv* env, jobject boolean_object) {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jclass> jboolean_clazz =
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetClass(env, "java/lang/Boolean");
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jmethodID boolean_value = MethodID::Get<MethodID::TYPE_INSTANCE>(
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env, jboolean_clazz.obj(), "booleanValue", "()Z");
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return env->CallBooleanMethod(boolean_object, boolean_value, NULL);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::Time ConvertJlongToTime(jlong value) {
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::Time::UnixEpoch() +
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::TimeDelta::FromMilliseconds((int64)value);
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ConvertJIntegerToJint(JNIEnv* env, jobject integer_obj) {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jclass> jinteger_clazz =
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GetClass(env, "java/lang/Integer");
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jmethodID int_value = MethodID::Get<MethodID::TYPE_INSTANCE>(
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env, jinteger_clazz.obj(), "intValue", "()I");
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return env->CallIntMethod(integer_obj, int_value, NULL);
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)std::vector<base::string16> ConvertJStringArrayToString16Array(
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    JNIEnv* env,
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    jobjectArray array) {
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> results;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (array) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jsize len = env->GetArrayLength(array);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < len; i++) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      results.push_back(ConvertJavaStringToUTF16(env,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          static_cast<jstring>(env->GetObjectArrayElement(array, i))));
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return results;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Utility methods used by tasks ------------- //
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parse the given url and return a GURL, appending the default scheme
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// if one is not present.
170a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)GURL ParseAndMaybeAppendScheme(const base::string16& url,
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const char* default_scheme) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL gurl(url);
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!gurl.is_valid() && !gurl.has_scheme()) {
1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::string16 refined_url(base::ASCIIToUTF16(default_scheme));
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    refined_url.append(url);
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    gurl = GURL(refined_url);
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gurl;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const BookmarkNode* GetChildFolderByTitle(const BookmarkNode* parent,
182a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                          const base::string16& title) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int i = 0; i < parent->child_count(); ++i) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (parent->GetChild(i)->is_folder() &&
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parent->GetChild(i)->GetTitle() == title) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return parent->GetChild(i);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Synchronous task classes ------------- //
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility task to add a bookmark.
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddBookmarkTask : public BookmarkModelTask {
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit AddBookmarkTask(BookmarkModel* model) : BookmarkModelTask(model) {}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
199a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 Run(const base::string16& title,
200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)            const base::string16& url,
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const bool is_folder,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const int64 parent_id) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 result = kInvalidBookmarkId;
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AddBookmarkTask::RunOnUIThread,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), title, url, is_folder, parent_id, &result));
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
211a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& title,
212a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& url,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const bool is_folder,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 parent_id,
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int64* result) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(result);
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL gurl = ParseAndMaybeAppendScheme(url, kDefaultUrlScheme);
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Check if the bookmark already exists.
22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const BookmarkNode* node = model->GetMostRecentlyAddedUserNodeForURL(gurl);
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!node) {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BookmarkNode* parent_node = NULL;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (parent_id >= 0)
225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        parent_node = bookmarks::GetBookmarkNodeByID(model, parent_id);
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!parent_node)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        parent_node = model->bookmark_bar_node();
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (is_folder)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        node = model->AddFolder(parent_node, parent_node->child_count(), title);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        node = model->AddURL(parent_node, 0, title, gurl);
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = node ? node ->id() : kInvalidBookmarkId;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddBookmarkTask);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility method to remove a bookmark.
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoveBookmarkTask : public BookmarkModelObserverTask {
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit RemoveBookmarkTask(BookmarkModel* model)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelObserverTask(model),
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        deleted_(0),
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        id_to_delete_(kInvalidBookmarkId) {}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~RemoveBookmarkTask() {}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const int64 id) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id_to_delete_ = id;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&RemoveBookmarkTask::RunOnUIThread, model(), id));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return deleted_;
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model, const int64 id) {
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
260116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, id);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node && node->parent()) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BookmarkNode* parent_node = node->parent();
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      model->Remove(parent_node, parent_node->GetIndexOf(node));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the bookmark was actually removed. Called synchronously.
268010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  virtual void BookmarkNodeRemoved(
269010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      BookmarkModel* bookmark_model,
270010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const BookmarkNode* parent,
271010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      int old_index,
272010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const BookmarkNode* node,
273010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      const std::set<GURL>& removed_urls) OVERRIDE {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bookmark_model == model() && node->id() == id_to_delete_)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ++deleted_;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int deleted_;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 id_to_delete_;
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoveBookmarkTask);
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Utility method to remove all bookmarks that the user can edit.
286f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class RemoveAllUserBookmarksTask : public BookmarkModelObserverTask {
287c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) public:
288f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  explicit RemoveAllUserBookmarksTask(BookmarkModel* model)
289c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      : BookmarkModelObserverTask(model) {}
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
291f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  virtual ~RemoveAllUserBookmarksTask() {}
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  void Run() {
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    RunOnUIThreadBlocking::Run(
295f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&RemoveAllUserBookmarksTask::RunOnUIThread, model()));
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model) {
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
300f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    model->RemoveAllUserBookmarks();
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) private:
304f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoveAllUserBookmarksTask);
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)};
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Utility method to update a bookmark.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UpdateBookmarkTask : public BookmarkModelObserverTask {
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit UpdateBookmarkTask(BookmarkModel* model)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelObserverTask(model),
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        updated_(0),
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        id_to_update_(kInvalidBookmarkId){}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~UpdateBookmarkTask() {}
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const int64 id,
317a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const base::string16& title,
318a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const base::string16& url,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const int64 parent_id) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    id_to_update_ = id;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&UpdateBookmarkTask::RunOnUIThread,
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), id, title, url, parent_id));
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return updated_;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 id,
329a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& title,
330a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& url,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 parent_id) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
333116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, id);
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node) {
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (node->GetTitle() != title)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        model->SetTitle(node, title);
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (node->type() == BookmarkNode::URL) {
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GURL bookmark_url = ParseAndMaybeAppendScheme(url, kDefaultUrlScheme);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (bookmark_url != node->url())
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          model->SetURL(node, bookmark_url);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (parent_id >= 0 &&
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          (!node->parent() || parent_id != node->parent()->id())) {
346116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        const BookmarkNode* new_parent =
347116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch            bookmarks::GetBookmarkNodeByID(model, parent_id);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (new_parent)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          model->Move(node, new_parent, 0);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Verify that the bookmark was actually updated. Called synchronously.
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void BookmarkNodeChanged(BookmarkModel* bookmark_model,
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const BookmarkNode* node) OVERRIDE {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (bookmark_model == model() && node->id() == id_to_update_)
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ++updated_;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int updated_;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 id_to_update_;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateBookmarkTask);
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks if a node exists in the bookmark model.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkNodeExistsTask : public BookmarkModelTask {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit BookmarkNodeExistsTask(BookmarkModel* model)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelTask(model) {
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Run(const int64 id) {
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result = false;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&BookmarkNodeExistsTask::RunOnUIThread,
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), id, &result));
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 id,
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool* result) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(result);
389116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    *result = bookmarks::GetBookmarkNodeByID(model, id) != NULL;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkNodeExistsTask);
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Checks if a node belongs to the Mobile Bookmarks hierarchy branch.
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IsInMobileBookmarksBranchTask : public BookmarkModelTask {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit IsInMobileBookmarksBranchTask(BookmarkModel* model)
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelTask(model) {}
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Run(const int64 id) {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool result = false;
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&IsInMobileBookmarksBranchTask::RunOnUIThread,
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), id, &result));
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 id,
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool *result) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(result);
415116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, id);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* mobile_node = model->mobile_node();
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (node && node != mobile_node)
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      node = node->parent();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = node == mobile_node;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(IsInMobileBookmarksBranchTask);
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates folder or retrieves its id if already exists.
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An invalid parent id is assumed to represent the Mobile Bookmarks folder.
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Can only be used to create folders inside the Mobile Bookmarks branch.
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CreateBookmarksFolderOnceTask : public BookmarkModelTask {
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit CreateBookmarksFolderOnceTask(BookmarkModel* model)
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelTask(model) {}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int64 Run(const base::string16& title, const int64 parent_id) {
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int64 result = kInvalidBookmarkId;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&CreateBookmarksFolderOnceTask::RunOnUIThread,
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), title, parent_id, &result));
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
444a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                            const base::string16& title,
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 parent_id,
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            int64* result) {
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(result);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Invalid ids are assumed to refer to the Mobile Bookmarks folder.
451116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BookmarkNode* parent =
452116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        parent_id >= 0 ? bookmarks::GetBookmarkNodeByID(model, parent_id)
453116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                       : model->mobile_node();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(parent);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool in_mobile_bookmarks;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    IsInMobileBookmarksBranchTask::RunOnUIThread(model, parent->id(),
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 &in_mobile_bookmarks);
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!in_mobile_bookmarks) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      // The parent folder must be inside the Mobile Bookmarks folder.
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = kInvalidBookmarkId;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* node = GetChildFolderByTitle(parent, title);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node) {
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = node->id();
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
471a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    AddBookmarkTask::RunOnUIThread(model, title, base::string16(), true,
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   parent->id(), result);
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(CreateBookmarksFolderOnceTask);
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a Java BookmarkNode object for a node given its id.
480f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)class GetEditableBookmarkFoldersTask : public BookmarkModelTask {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
482f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetEditableBookmarkFoldersTask(ChromeBookmarkClient* client,
483f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                 BookmarkModel* model)
484f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      : BookmarkModelTask(model), client_(client) {}
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Run(ScopedJavaGlobalRef<jobject>* jroot) {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
488f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&GetEditableBookmarkFoldersTask::RunOnUIThread,
489f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                   client_, model(), jroot));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
492f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static void RunOnUIThread(ChromeBookmarkClient* client,
493f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                            BookmarkModel* model,
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ScopedJavaGlobalRef<jobject>* jroot) {
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* root = model->root_node();
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!root || !root->is_folder())
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // The iterative approach is not possible because ScopedGlobalJavaRefs
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // cannot be copy-constructed, and therefore not used in STL containers.
502f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    ConvertFolderSubtree(client, AttachCurrentThread(), root,
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         ScopedJavaLocalRef<jobject>(), jroot);
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
507f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  static void ConvertFolderSubtree(ChromeBookmarkClient* client,
508f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)                                   JNIEnv* env,
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const BookmarkNode* node,
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   const JavaRef<jobject>& parent_folder,
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   ScopedJavaGlobalRef<jobject>* jfolder) {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(node);
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(node->is_folder());
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(jfolder);
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Global refs should be used here for thread-safety reasons as this task
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // might be invoked from a thread other than UI. All refs are scoped.
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertBookmarkNode(node, parent_folder, jfolder);
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < node->child_count(); ++i) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const BookmarkNode* child = node->GetChild(i);
522f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      if (child->is_folder() && client->CanBeEditedByUser(child)) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ScopedJavaGlobalRef<jobject> jchild;
524f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        ConvertFolderSubtree(client, env, child, *jfolder, &jchild);
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Java_BookmarkNode_addChild(env, jfolder->obj(), jchild.obj());
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ClearException(env)) {
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          LOG(WARNING) << "Java exception while adding child node.";
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ChromeBookmarkClient* client_;
536f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)
537f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetEditableBookmarkFoldersTask);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Creates a Java BookmarkNode object for a node given its id.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GetBookmarkNodeTask : public BookmarkModelTask {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit GetBookmarkNodeTask(BookmarkModel* model)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelTask(model) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Run(const int64 id,
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           bool get_parent,
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           bool get_children,
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ScopedJavaGlobalRef<jobject>* jnode) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return RunOnUIThreadBlocking::Run(
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&GetBookmarkNodeTask::RunOnUIThread,
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), id, get_parent, get_children, jnode));
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model,
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            const int64 id,
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool get_parent,
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            bool get_children,
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            ScopedJavaGlobalRef<jobject>* jnode) {
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
562116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const BookmarkNode* node = bookmarks::GetBookmarkNodeByID(model, id);
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!node || !jnode)
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedJavaGlobalRef<jobject> jparent;
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (get_parent) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertBookmarkNode(node->parent(), ScopedJavaLocalRef<jobject>(),
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          &jparent);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ConvertBookmarkNode(node, jparent, jnode);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env = AttachCurrentThread();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!jparent.is_null()) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      Java_BookmarkNode_addChild(env, jparent.obj(), jnode->obj());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (ClearException(env)) {
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(WARNING) << "Java exception while adding child node.";
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (get_children) {
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int i = 0; i < node->child_count(); ++i) {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ScopedJavaGlobalRef<jobject> jchild;
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ConvertBookmarkNode(node->GetChild(i), *jnode, &jchild);
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        Java_BookmarkNode_addChild(env, jnode->obj(), jchild.obj());
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (ClearException(env)) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          LOG(WARNING) << "Java exception while adding child node.";
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          return;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetBookmarkNodeTask);
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Gets the Mobile Bookmarks node. Using this task ensures the correct
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialization of the bookmark model.
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class GetMobileBookmarksNodeTask : public BookmarkModelTask {
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit GetMobileBookmarksNodeTask(BookmarkModel* model)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : BookmarkModelTask(model) {}
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const BookmarkNode* Run() {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const BookmarkNode* result = NULL;
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunOnUIThreadBlocking::Run(
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&GetMobileBookmarksNodeTask::RunOnUIThread,
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   model(), &result));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result;
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static void RunOnUIThread(BookmarkModel* model, const BookmarkNode** result) {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(result);
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *result = model->mobile_node();
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(GetMobileBookmarksNodeTask);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Aynchronous requests classes ------------- //
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for asynchronous blocking requests to Chromium services.
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Service: type of the service to use (e.g. HistoryService, FaviconService).
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)template <typename Service>
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AsyncServiceRequest : protected BlockingUIThreadAsyncRequest {
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AsyncServiceRequest(Service* service,
633116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      base::CancelableTaskTracker* cancelable_tracker)
6345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : service_(service), cancelable_tracker_(cancelable_tracker) {}
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Service* service() const { return service_; }
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
638116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::CancelableTaskTracker* cancelable_tracker() const {
639116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return cancelable_tracker_;
640116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
641116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Service* service_;
644116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::CancelableTaskTracker* cancelable_tracker_;
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AsyncServiceRequest);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for all asynchronous blocking tasks that use the favicon service.
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FaviconServiceTask : public AsyncServiceRequest<FaviconService> {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
652e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  FaviconServiceTask(base::CancelableTaskTracker* cancelable_tracker,
6535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                     Profile* profile)
654e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      : AsyncServiceRequest<FaviconService>(
655e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch            FaviconServiceFactory::GetForProfile(profile,
656e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch                                                 Profile::EXPLICIT_ACCESS),
657e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch            cancelable_tracker),
658116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        profile_(profile) {}
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile() const { return profile_; }
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FaviconServiceTask);
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Retrieves the favicon or touch icon for a URL from the FaviconService.
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BookmarkIconFetchTask : public FaviconServiceTask {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
671e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  BookmarkIconFetchTask(base::CancelableTaskTracker* cancelable_tracker,
6725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        Profile* profile)
673e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      : FaviconServiceTask(cancelable_tracker, profile) {}
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_base::FaviconRawBitmapResult Run(const GURL& url) {
676116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    float max_scale = ui::GetScaleForScaleFactor(
677116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        ResourceBundle::GetSharedInstance().GetMaxScaleFactor());
678116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    int desired_size_in_pixel = std::ceil(gfx::kFaviconSize * max_scale);
679e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
680e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    if (service() == NULL)
681e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      return favicon_base::FaviconRawBitmapResult();
682e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
684f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)        base::Bind(&FaviconService::GetRawFaviconForPageURL,
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(service()),
686116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   url,
687116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   favicon_base::FAVICON | favicon_base::TOUCH_ICON,
688116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   desired_size_in_pixel,
6890529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                   base::Bind(&BookmarkIconFetchTask::OnFaviconRetrieved,
6900529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch                              base::Unretained(this)),
6912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                   cancelable_tracker()));
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
6960529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  void OnFaviconRetrieved(
697f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const favicon_base::FaviconRawBitmapResult& bitmap_result) {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = bitmap_result;
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
702f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_base::FaviconRawBitmapResult result_;
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(BookmarkIconFetchTask);
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Base class for all asynchronous blocking tasks that use the Android history
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provider service.
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class HistoryProviderTask
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : public AsyncServiceRequest<AndroidHistoryProviderService> {
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  HistoryProviderTask(AndroidHistoryProviderService* service,
713116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                      base::CancelableTaskTracker* cancelable_tracker)
714116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      : AsyncServiceRequest<AndroidHistoryProviderService>(service,
715116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                           cancelable_tracker) {
716116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(HistoryProviderTask);
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a bookmark from the API.
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddBookmarkFromAPITask : public HistoryProviderTask {
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddBookmarkFromAPITask(AndroidHistoryProviderService* service,
726116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                         base::CancelableTaskTracker* cancelable_tracker)
7275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker) {}
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLID Run(const history::HistoryAndBookmarkRow& row) {
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AndroidHistoryProviderService::InsertHistoryAndBookmark,
732116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(service()),
733116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   row,
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&AddBookmarkFromAPITask::OnBookmarkInserted,
735116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              base::Unretained(this)),
736116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   cancelable_tracker()));
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
741116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnBookmarkInserted(history::URLID id) {
742116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Note that here 0 means an invalid id.
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is because it represents a SQLite database row id.
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = id;
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLID result_;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddBookmarkFromAPITask);
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Queries bookmarks from the API.
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QueryBookmarksFromAPITask : public HistoryProviderTask {
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  QueryBookmarksFromAPITask(AndroidHistoryProviderService* service,
757116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                            base::CancelableTaskTracker* cancelable_tracker)
7585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker), result_(NULL) {}
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* Run(
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<history::HistoryAndBookmarkRow::ColumnID>& projections,
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& selection,
763a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<base::string16>& selection_args,
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& sort_order) {
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AndroidHistoryProviderService::QueryHistoryAndBookmarks,
767116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(service()),
768116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   projections,
769116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   selection,
770116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   selection_args,
771116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   sort_order,
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&QueryBookmarksFromAPITask::OnBookmarksQueried,
773116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              base::Unretained(this)),
774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   cancelable_tracker()));
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnBookmarksQueried(history::AndroidStatement* statement) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = statement;
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* result_;
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QueryBookmarksFromAPITask);
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Updates bookmarks from the API.
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UpdateBookmarksFromAPITask : public HistoryProviderTask {
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateBookmarksFromAPITask(AndroidHistoryProviderService* service,
793116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             base::CancelableTaskTracker* cancelable_tracker)
7945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker), result_(0) {}
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const history::HistoryAndBookmarkRow& row,
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const std::string& selection,
798a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const std::vector<base::string16>& selection_args) {
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AndroidHistoryProviderService::UpdateHistoryAndBookmarks,
801116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(service()),
802116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   row,
803116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   selection,
804116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   selection_args,
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&UpdateBookmarksFromAPITask::OnBookmarksUpdated,
806116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              base::Unretained(this)),
807116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   cancelable_tracker()));
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
812116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnBookmarksUpdated(int updated_row_count) {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = updated_row_count;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result_;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateBookmarksFromAPITask);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Removes bookmarks from the API.
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoveBookmarksFromAPITask : public HistoryProviderTask {
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveBookmarksFromAPITask(AndroidHistoryProviderService* service,
826116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             base::CancelableTaskTracker* cancelable_tracker)
8275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker), result_(0) {}
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const std::string& selection,
830a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const std::vector<base::string16>& selection_args) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AndroidHistoryProviderService::DeleteHistoryAndBookmarks,
8335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::Unretained(service()),
8345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   selection,
8355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   selection_args,
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&RemoveBookmarksFromAPITask::OnBookmarksRemoved,
8375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Unretained(this)),
8385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   cancelable_tracker()));
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnBookmarksRemoved(int removed_row_count) {
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = removed_row_count;
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result_;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoveBookmarksFromAPITask);
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Removes history from the API.
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoveHistoryFromAPITask : public HistoryProviderTask {
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveHistoryFromAPITask(AndroidHistoryProviderService* service,
857116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           base::CancelableTaskTracker* cancelable_tracker)
8585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker), result_(0) {}
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const std::string& selection,
861a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const std::vector<base::string16>& selection_args) {
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AndroidHistoryProviderService::DeleteHistory,
8645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::Unretained(service()),
8655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   selection,
8665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   selection_args,
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Bind(&RemoveHistoryFromAPITask::OnHistoryRemoved,
8685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                              base::Unretained(this)),
8695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   cancelable_tracker()));
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
8745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnHistoryRemoved(int removed_row_count) {
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = removed_row_count;
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result_;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoveHistoryFromAPITask);
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class provides the common method for the SearchTermAPIHelper.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SearchTermTask : public HistoryProviderTask {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SearchTermTask(AndroidHistoryProviderService* service,
888116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                 base::CancelableTaskTracker* cancelable_tracker,
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 Profile* profile)
8905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : HistoryProviderTask(service, cancelable_tracker), profile_(profile) {}
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
892116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Fill SearchRow's keyword_id and url fields according the given
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // search_term. Return true if succeeded.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BuildSearchRow(history::SearchRow* row) {
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TemplateURLService* template_service =
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TemplateURLServiceFactory::GetForProfile(profile_);
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template_service->Load();
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const TemplateURL* search_engine =
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        template_service->GetDefaultSearchProvider();
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (search_engine) {
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const TemplateURLRef* search_url = &search_engine->url_ref();
905eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      TemplateURLRef::SearchTermsArgs search_terms_args(row->search_term());
906eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      search_terms_args.append_extra_query_params = true;
907f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      std::string url = search_url->ReplaceSearchTerms(
908f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)          search_terms_args, template_service->search_terms_data());
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (!url.empty()) {
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        row->set_url(GURL(url));
911116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        row->set_keyword_id(search_engine->id());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Profile* profile_;
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SearchTermTask);
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Adds a search term from the API.
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AddSearchTermFromAPITask : public SearchTermTask {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
925116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddSearchTermFromAPITask(AndroidHistoryProviderService* service,
926116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           base::CancelableTaskTracker* cancelable_tracker,
927116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                           Profile* profile)
9285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : SearchTermTask(service, cancelable_tracker, profile) {}
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLID Run(const history::SearchRow& row) {
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AddSearchTermFromAPITask::MakeRequestOnUIThread,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), row));
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void MakeRequestOnUIThread(const history::SearchRow& row) {
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::SearchRow internal_row = row;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BuildSearchRow(&internal_row);
942116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    service()->InsertSearchTerm(
943116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        internal_row,
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&AddSearchTermFromAPITask::OnSearchTermInserted,
945116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(this)),
946116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        cancelable_tracker());
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
949116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnSearchTermInserted(history::URLID id) {
950116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Note that here 0 means an invalid id.
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // This is because it represents a SQLite database row id.
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = id;
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::URLID result_;
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AddSearchTermFromAPITask);
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Queries search terms from the API.
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class QuerySearchTermsFromAPITask : public SearchTermTask {
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
964116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  QuerySearchTermsFromAPITask(AndroidHistoryProviderService* service,
965116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              base::CancelableTaskTracker* cancelable_tracker,
966116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                              Profile* profile)
9675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : SearchTermTask(service, cancelable_tracker, profile), result_(NULL) {}
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* Run(
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<history::SearchRow::ColumnID>& projections,
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& selection,
972a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<base::string16>& selection_args,
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::string& sort_order) {
974116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    RunAsyncRequestOnUIThreadBlocking(base::Bind(
975116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        &AndroidHistoryProviderService::QuerySearchTerms,
976116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Unretained(service()),
977116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        projections,
978116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        selection,
979116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        selection_args,
980116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        sort_order,
981116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        base::Bind(&QuerySearchTermsFromAPITask::OnSearchTermsQueried,
982116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(this)),
983116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        cancelable_tracker()));
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Callback to return the result.
989116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnSearchTermsQueried(history::AndroidStatement* statement) {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = statement;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* result_;
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(QuerySearchTermsFromAPITask);
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Updates search terms from the API.
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class UpdateSearchTermsFromAPITask : public SearchTermTask {
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1002116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdateSearchTermsFromAPITask(AndroidHistoryProviderService* service,
1003116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               base::CancelableTaskTracker* cancelable_tracker,
1004116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               Profile* profile)
10055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : SearchTermTask(service, cancelable_tracker, profile), result_(0) {}
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const history::SearchRow& row,
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          const std::string& selection,
1009a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const std::vector<base::string16>& selection_args) {
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&UpdateSearchTermsFromAPITask::MakeRequestOnUIThread,
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   base::Unretained(this), row, selection, selection_args));
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1017a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void MakeRequestOnUIThread(
1018a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const history::SearchRow& row,
1019a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::string& selection,
1020a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const std::vector<base::string16>& selection_args) {
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    history::SearchRow internal_row = row;
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BuildSearchRow(&internal_row);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    service()->UpdateSearchTerms(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        internal_row,
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        selection,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        selection_args,
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        base::Bind(&UpdateSearchTermsFromAPITask::OnSearchTermsUpdated,
1029116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                   base::Unretained(this)),
1030116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        cancelable_tracker());
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1033116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  void OnSearchTermsUpdated(int updated_row_count) {
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = updated_row_count;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result_;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(UpdateSearchTermsFromAPITask);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Removes search terms from the API.
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class RemoveSearchTermsFromAPITask : public SearchTermTask {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1046116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RemoveSearchTermsFromAPITask(AndroidHistoryProviderService* service,
1047116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               base::CancelableTaskTracker* cancelable_tracker,
1048116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                               Profile* profile)
10495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      : SearchTermTask(service, cancelable_tracker, profile), result_() {}
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int Run(const std::string& selection,
1052a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          const std::vector<base::string16>& selection_args) {
10535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    RunAsyncRequestOnUIThreadBlocking(base::Bind(
10545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        &AndroidHistoryProviderService::DeleteSearchTerms,
10555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Unretained(service()),
10565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        selection,
10575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        selection_args,
10585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        base::Bind(&RemoveSearchTermsFromAPITask::OnSearchTermsDeleted,
10595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                   base::Unretained(this)),
10605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        cancelable_tracker()));
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return result_;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
10655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  void OnSearchTermsDeleted(int deleted_row_count) {
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result_ = deleted_row_count;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    RequestCompleted();
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int result_;
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(RemoveSearchTermsFromAPITask);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Other utility methods (may use tasks) ------------- //
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills the bookmark |row| with the given java objects.
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillBookmarkRow(JNIEnv* env,
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jobject obj,
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jstring url,
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jobject created,
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jobject isBookmark,
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jobject date,
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jbyteArray favicon,
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jstring title,
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jobject visits,
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     jlong parent_id,
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     history::HistoryAndBookmarkRow* row,
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     BookmarkModel* model) {
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Needed because of the internal bookmark model task invocation.
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::UI));
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (url) {
1094a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    base::string16 raw_url = ConvertJavaStringToUTF16(env, url);
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GURL doesn't accept the URL without protocol, but the Android CTS
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // allows it. We are trying to prefix with 'http://' to see whether
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // GURL thinks it is a valid URL. The original url will be stored in
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // history::BookmarkRow.raw_url_.
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL gurl = ParseAndMaybeAppendScheme(raw_url, kDefaultUrlScheme);
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_url(gurl);
11015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    row->set_raw_url(base::UTF16ToUTF8(raw_url));
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (created)
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_created(ConvertJlongToTime(
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ConvertJLongObjectToPrimitive(env, created)));
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (isBookmark)
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_is_bookmark(ConvertJBooleanObjectToPrimitive(env, isBookmark));
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (date)
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_last_visit_time(ConvertJlongToTime(ConvertJLongObjectToPrimitive(
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        env, date)));
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (favicon) {
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    std::vector<uint8> bytes;
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::android::JavaByteArrayToByteVector(env, favicon, &bytes);
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_favicon(base::RefCountedBytes::TakeVector(&bytes));
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (title)
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_title(ConvertJavaStringToUTF16(env, title));
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (visits)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_visit_count(ConvertJIntegerToJint(env, visits));
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Make sure parent_id is always in the mobile_node branch.
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IsInMobileBookmarksBranchTask task(model);
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (task.Run(parent_id))
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_parent_id(parent_id);
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fills the bookmark |row| with the given java objects if it is not null.
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void FillSearchRow(JNIEnv* env,
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   jobject obj,
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   jstring search_term,
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   jobject date,
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                   history::SearchRow* row) {
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (search_term)
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_search_term(ConvertJavaStringToUTF16(env, search_term));
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (date)
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    row->set_search_time(ConvertJlongToTime(ConvertJLongObjectToPrimitive(
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        env, date)));
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Native initialization and destruction ------------- //
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1151f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)static jlong Init(JNIEnv* env, jobject obj) {
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ChromeBrowserProvider* provider = new ChromeBrowserProvider(env, obj);
1153f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return reinterpret_cast<intptr_t>(provider);
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeBrowserProvider::RegisterChromeBrowserProvider(JNIEnv* env) {
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return RegisterNativesImpl(env);
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeBrowserProvider::ChromeBrowserProvider(JNIEnv* env, jobject obj)
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : weak_java_provider_(env, obj),
11627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      handling_extensive_changes_(false) {
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  profile_ = g_browser_process->profile_manager()->GetLastUsedProfile();
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_model_ = BookmarkModelFactory::GetForProfile(profile_);
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  top_sites_ = profile_->GetTopSites();
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  service_.reset(new AndroidHistoryProviderService(profile_));
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers the notifications we are interested.
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_model_->AddObserver(this);
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URL_VISITED,
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this, chrome::NOTIFICATION_HISTORY_URLS_DELETED,
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              content::NotificationService::AllSources());
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  notification_registrar_.Add(this,
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED,
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      content::NotificationService::AllSources());
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TemplateURLService* template_service =
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        TemplateURLServiceFactory::GetForProfile(profile_);
11807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!template_service->loaded())
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template_service->Load();
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ChromeBrowserProvider::~ChromeBrowserProvider() {
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bookmark_model_->RemoveObserver(this);
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeBrowserProvider::Destroy(JNIEnv*, jobject) {
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  delete this;
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Provider public APIs ------------- //
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jlong ChromeBrowserProvider::AddBookmark(JNIEnv* env,
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jobject,
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jstring jurl,
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jstring jtitle,
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jboolean is_folder,
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         jlong parent_id) {
1200a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 url;
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (jurl)
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = ConvertJavaStringToUTF16(env, jurl);
1203a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 title = ConvertJavaStringToUTF16(env, jtitle);
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AddBookmarkTask task(bookmark_model_);
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(title, url, is_folder, parent_id);
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::RemoveBookmark(JNIEnv*, jobject, jlong id) {
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  RemoveBookmarkTask task(bookmark_model_);
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(id);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::UpdateBookmark(JNIEnv* env,
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           jobject,
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           jlong id,
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           jstring jurl,
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           jstring jtitle,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           jlong parent_id) {
1220a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 url;
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (jurl)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    url = ConvertJavaStringToUTF16(env, jurl);
1223a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 title = ConvertJavaStringToUTF16(env, jtitle);
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  UpdateBookmarkTask task(bookmark_model_);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(id, title, url, parent_id);
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Add the bookmark with the given column values.
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jlong ChromeBrowserProvider::AddBookmarkFromAPI(JNIEnv* env,
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jobject obj,
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jstring url,
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jobject created,
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jobject isBookmark,
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jobject date,
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jbyteArray favicon,
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jstring title,
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jobject visits,
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                jlong parent_id) {
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(url);
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::HistoryAndBookmarkRow row;
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillBookmarkRow(env, obj, url, created, isBookmark, date, favicon, title,
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  visits, parent_id, &row, bookmark_model_);
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL must be valid.
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (row.url().is_empty()) {
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Not a valid URL " << row.raw_url();
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return kInvalidContentProviderId;
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  AddBookmarkFromAPITask task(service_.get(), &cancelable_task_tracker_);
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(row);
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ChromeBrowserProvider::QueryBookmarkFromAPI(
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj,
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobjectArray projection,
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring selections,
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobjectArray selection_args,
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring sort_order) {
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts the projection to array of ColumnID and column name.
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to store the projection column ID according their sequence.
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<history::HistoryAndBookmarkRow::ColumnID> query_columns;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to store the projection column names according their sequence.
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> columns_name;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (projection) {
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jsize len = env->GetArrayLength(projection);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < len; i++) {
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name = ConvertJavaStringToUTF8(env, static_cast<jstring>(
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          env->GetObjectArrayElement(projection, i)));
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::HistoryAndBookmarkRow::ColumnID id =
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          history::HistoryAndBookmarkRow::GetColumnID(name);
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (id == history::HistoryAndBookmarkRow::COLUMN_END) {
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Ignore the unknown column; As Android platform will send us
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // the non public column.
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        continue;
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_columns.push_back(id);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      columns_name.push_back(name);
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1285a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections) {
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sort_clause;
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sort_order) {
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sort_clause = ConvertJavaStringToUTF8(env, sort_order);
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  QueryBookmarksFromAPITask task(service_.get(), &cancelable_task_tracker_);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* statement = task.Run(
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_columns, where_clause, where_args, sort_clause);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!statement)
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jobject>();
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1304e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
1305e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      profile_, Profile::EXPLICIT_ACCESS);
1306e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
1307e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (!favicon_service)
1308e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return ScopedJavaLocalRef<jobject>();
1309e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and returns org.chromium.chrome.browser.database.SQLiteCursor
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Java object.
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLiteCursor::NewJavaSqliteCursor(env, columns_name, statement,
1313e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch             service_.get(), favicon_service);
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Updates the bookmarks with the given column values. The value is not given if
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it is NULL.
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::UpdateBookmarkFromAPI(JNIEnv* env,
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject obj,
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jstring url,
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject created,
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject isBookmark,
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject date,
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jbyteArray favicon,
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jstring title,
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject visits,
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jlong parent_id,
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jstring selections,
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobjectArray selection_args) {
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::HistoryAndBookmarkRow row;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillBookmarkRow(env, obj, url, created, isBookmark, date, favicon, title,
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  visits, parent_id, &row, bookmark_model_);
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1334a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections)
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  UpdateBookmarksFromAPITask task(service_.get(), &cancelable_task_tracker_);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(row, where_clause, where_args);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::RemoveBookmarkFromAPI(JNIEnv* env,
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject obj,
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jstring selections,
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobjectArray selection_args) {
1349a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveBookmarksFromAPITask task(service_.get(), &cancelable_task_tracker_);
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(where_clause, where_args);
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::RemoveHistoryFromAPI(JNIEnv* env,
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 jobject obj,
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 jstring selections,
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 jobjectArray selection_args) {
1364a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections)
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  RemoveHistoryFromAPITask task(service_.get(), &cancelable_task_tracker_);
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(where_clause, where_args);
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Add the search term with the given column values. The value is not given if
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// it is NULL.
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jlong ChromeBrowserProvider::AddSearchTermFromAPI(JNIEnv* env,
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject obj,
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jstring search_term,
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  jobject date) {
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(search_term);
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::SearchRow row;
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillSearchRow(env, obj, search_term, date, &row);
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URL must be valid.
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (row.search_term().empty()) {
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Search term is empty.";
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return kInvalidContentProviderId;
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1392116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  AddSearchTermFromAPITask task(service_.get(),
1393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                &cancelable_task_tracker_,
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                profile_);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(row);
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ChromeBrowserProvider::QuerySearchTermFromAPI(
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj,
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobjectArray projection,
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring selections,
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobjectArray selection_args,
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring sort_order) {
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Converts the projection to array of ColumnID and column name.
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to store the projection column ID according their sequence.
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<history::SearchRow::ColumnID> query_columns;
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Used to store the projection column names according their sequence.
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::vector<std::string> columns_name;
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (projection) {
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jsize len = env->GetArrayLength(projection);
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < len; i++) {
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      std::string name = ConvertJavaStringToUTF8(env, static_cast<jstring>(
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          env->GetObjectArrayElement(projection, i)));
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::SearchRow::ColumnID id =
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          history::SearchRow::GetColumnID(name);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (id == history::SearchRow::COLUMN_END) {
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        LOG(ERROR) << "Can not find " << name;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return ScopedJavaLocalRef<jobject>();
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_columns.push_back(id);
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      columns_name.push_back(name);
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1426a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections) {
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string sort_clause;
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sort_order) {
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sort_clause = ConvertJavaStringToUTF8(env, sort_order);
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1439116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  QuerySearchTermsFromAPITask task(service_.get(),
1440116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                   &cancelable_task_tracker_,
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   profile_);
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* statement = task.Run(
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      query_columns, where_clause, where_args, sort_clause);
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!statement)
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jobject>();
1446e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
1447e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  FaviconService* favicon_service = FaviconServiceFactory::GetForProfile(
1448e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch      profile_, Profile::EXPLICIT_ACCESS);
1449e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
1450e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  if (!favicon_service)
1451e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch    return ScopedJavaLocalRef<jobject>();
1452e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates and returns org.chromium.chrome.browser.database.SQLiteCursor
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Java object.
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return SQLiteCursor::NewJavaSqliteCursor(env, columns_name, statement,
1456e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch             service_.get(), favicon_service);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Updates the search terms with the given column values. The value is not
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// given if it is NULL.
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::UpdateSearchTermFromAPI(
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env, jobject obj, jstring search_term, jobject date,
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring selections, jobjectArray selection_args) {
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::SearchRow row;
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FillSearchRow(env, obj, search_term, date, &row);
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1467a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args = ConvertJStringArrayToString16Array(
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      env, selection_args);
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections)
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1474116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  UpdateSearchTermsFromAPITask task(service_.get(),
1475116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    &cancelable_task_tracker_,
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    profile_);
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(row, where_clause, where_args);
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jint ChromeBrowserProvider::RemoveSearchTermFromAPI(
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env, jobject obj, jstring selections, jobjectArray selection_args) {
1482a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  std::vector<base::string16> where_args =
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ConvertJStringArrayToString16Array(env, selection_args);
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string where_clause;
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (selections)
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    where_clause = ConvertJavaStringToUTF8(env, selections);
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1489116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  RemoveSearchTermsFromAPITask task(service_.get(),
1490116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                    &cancelable_task_tracker_,
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    profile_);
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(where_clause, where_args);
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Provider custom APIs ------------- //
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jboolean ChromeBrowserProvider::BookmarkNodeExists(
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj,
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jlong id) {
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  BookmarkNodeExistsTask task(bookmark_model_);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(id);
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jlong ChromeBrowserProvider::CreateBookmarksFolderOnce(
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj,
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jstring jtitle,
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jlong parent_id) {
1510a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  base::string16 title = ConvertJavaStringToUTF16(env, jtitle);
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (title.empty())
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return kInvalidBookmarkId;
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateBookmarksFolderOnceTask task(bookmark_model_);
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(title, parent_id);
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1518f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetEditableBookmarkFolders(
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj) {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaGlobalRef<jobject> jroot;
1522f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  ChromeBookmarkClient* client =
1523f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      ChromeBookmarkClientFactory::GetForProfile(profile_);
1524f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  BookmarkModel* model = BookmarkModelFactory::GetForProfile(profile_);
1525f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  GetEditableBookmarkFoldersTask task(client, model);
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task.Run(&jroot);
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ScopedJavaLocalRef<jobject>(jroot);
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1530f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)void ChromeBrowserProvider::RemoveAllUserBookmarks(JNIEnv* env, jobject obj) {
1531f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  RemoveAllUserBookmarksTask task(bookmark_model_);
1532c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  task.Run();
1533c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
1534c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetBookmarkNode(
1536c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    JNIEnv* env, jobject obj, jlong id, jboolean get_parent,
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jboolean get_children) {
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaGlobalRef<jobject> jnode;
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetBookmarkNodeTask task(bookmark_model_);
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  task.Run(id, get_parent, get_children, &jnode);
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ScopedJavaLocalRef<jobject>(jnode);
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jobject> ChromeBrowserProvider::GetMobileBookmarksFolder(
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj) {
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaGlobalRef<jobject> jnode;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetMobileBookmarksNodeTask task(bookmark_model_);
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ConvertBookmarkNode(task.Run(), ScopedJavaLocalRef<jobject>(), &jnode);
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ScopedJavaLocalRef<jobject>(jnode);
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)jboolean ChromeBrowserProvider::IsBookmarkInMobileBookmarksBranch(
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env,
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jobject obj,
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    jlong id) {
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IsInMobileBookmarksBranchTask task(bookmark_model_);
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return task.Run(id);
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jbyteArray> ChromeBrowserProvider::GetFaviconOrTouchIcon(
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env, jobject obj, jstring jurl) {
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!jurl)
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jbyteArray>();
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = GURL(ConvertJavaStringToUTF16(env, jurl));
1567e4256316f8b5e8d1ec0df1f7762771622a53fa63Ben Murdoch  BookmarkIconFetchTask favicon_task(&cancelable_task_tracker_, profile_);
1568f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_base::FaviconRawBitmapResult bitmap_result = favicon_task.Run(url);
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!bitmap_result.is_valid() || !bitmap_result.bitmap_data.get())
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jbyteArray>();
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::android::ToJavaByteArray(env, bitmap_result.bitmap_data->front(),
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        bitmap_result.bitmap_data->size());
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ScopedJavaLocalRef<jbyteArray> ChromeBrowserProvider::GetThumbnail(
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env, jobject obj, jstring jurl) {
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!jurl)
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jbyteArray>();
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url = GURL(ConvertJavaStringToUTF16(env, jurl));
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // GetPageThumbnail is synchronous and can be called from any thread.
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::RefCountedMemory> thumbnail;
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (top_sites_)
1586d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    top_sites_->GetPageThumbnail(url, false, &thumbnail);
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!thumbnail.get() || !thumbnail->front()) {
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ScopedJavaLocalRef<jbyteArray>();
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return base::android::ToJavaByteArray(env, thumbnail->front(),
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      thumbnail->size());
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ------------- Observer-related methods ------------- //
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ChromeBrowserProvider::ExtensiveBookmarkChangesBeginning(
15997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    BookmarkModel* model) {
16007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  handling_extensive_changes_ = true;
16017dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
16027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
16037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid ChromeBrowserProvider::ExtensiveBookmarkChangesEnded(
16047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    BookmarkModel* model) {
16057dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  handling_extensive_changes_ = false;
16067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  BookmarkModelChanged();
16077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
16087dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeBrowserProvider::BookmarkModelChanged() {
16107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (handling_extensive_changes_)
16117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    return;
16127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JNIEnv* env = AttachCurrentThread();
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (obj.is_null())
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Java_ChromeBrowserProvider_onBookmarkChanged(env, obj.obj());
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ChromeBrowserProvider::Observe(
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int type,
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationSource& source,
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const content::NotificationDetails& details) {
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (type == chrome::NOTIFICATION_HISTORY_URL_VISITED ||
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      type == chrome::NOTIFICATION_HISTORY_URLS_DELETED) {
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env = AttachCurrentThread();
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj.is_null())
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
16311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    Java_ChromeBrowserProvider_onHistoryChanged(env, obj.obj());
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (type ==
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::NOTIFICATION_HISTORY_KEYWORD_SEARCH_TERM_UPDATED) {
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JNIEnv* env = AttachCurrentThread();
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedJavaLocalRef<jobject> obj = weak_java_provider_.get(env);
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj.is_null())
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return;
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Java_ChromeBrowserProvider_onSearchTermChanged(env, obj.obj());
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1641