sqlite_cursor.h revision f8ee788a64d60abd8f2d742a5fdedde054ecd910
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)#ifndef CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <jni.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/android/scoped_java_ref.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/gtest_prod_util.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string16.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/task/cancelable_task_tracker.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/common/cancelable_request.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/android/android_history_provider_service.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/history/history_types.h"
21cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "components/favicon_base/favicon_callback.h"
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)class FaviconService;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class is JNI implementation of
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// org.chromium.chrome.database.SqliteCursor, it uses the AndroidStatement to
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// iterate among the result rows. This is not thread safe, all methods should
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be called from the same non-UI thread which typical is the Java thread.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class can not be in history namespace because the class name has to
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// match to the generated sqlite_cursor_jni.h.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SQLiteCursor {
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Mapping to the column type definitions in java.sql.Types.
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  enum JavaColumnType {
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    BLOB = 2004,
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LONG_VAR_CHAR = -1,
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NULL_TYPE = 0,
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NUMERIC = 2,
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DOUBLE = 8,
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This class is intended to be used only in unit tests.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There are 2 threads in unit test, one is the UI thread, another is the DB
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // thread, after the task posted into UI thread, the MessageLoop needs to run
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to execute the task. The OnPostMoveToTask() and the OnPostGetFaviconTask()
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // give unit tests a chance to run the message loop before event_.Wait is
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // invoked, The OnGetMoveToResult() and OnGetFaviconResult() is used to notify
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the test observer in the UI thread when the task's result comes back, it
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // calls MessageLoop::Quit() to exit the loop, then the event.Wait() is
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // called. Basically, Two threads are used to simulate 3 threads' behavior
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // here.
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The whole observer design is only for test purpose and should only be used
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in unit test.
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class TestObserver {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    TestObserver();
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the MoveTo task has been posted to UI thread.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnPostMoveToTask() = 0;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the MoveTo result has been gotten in UI thread.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnGetMoveToResult() = 0;
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the GetFavicon task has been posted to UI thread.
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnPostGetFaviconTask() = 0;
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Notify the GetFavicon result has been gotten in UI thread.
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void OnGetFaviconResult() = 0;
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual ~TestObserver();
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns org.chromium.chrome.SQLiteCursor java object by creating
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SQLitCursor native and java objects, then bind them together.
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static base::android::ScopedJavaLocalRef<jobject> NewJavaSqliteCursor(
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      JNIEnv* env,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const std::vector<std::string>& column_names,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      history::AndroidStatement* statement,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      AndroidHistoryProviderService* service,
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      FaviconService* favicon_service);
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static bool RegisterSqliteCursor(JNIEnv* env);
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JNI methods -----------------------------------------------------------
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the result row count.
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jint GetCount(JNIEnv* env, jobject obj);
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the result's columns' name.
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jobjectArray> GetColumnNames(
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      JNIEnv* env,
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      jobject obj);
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the given column value as jstring.
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jstring> GetString(JNIEnv* env,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       jobject obj,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                       jint column);
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the given column value as jlong.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jlong GetLong(JNIEnv* env, jobject obj, jint column);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the given column value as int.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jint GetInt(JNIEnv* env, jobject obj, jint column);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the given column value as double.
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jdouble GetDouble(JNIEnv* env, jobject obj, jint column);
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the given column value as jbyteArray.
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::android::ScopedJavaLocalRef<jbyteArray> GetBlob(JNIEnv* env,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        jobject obj,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        jint column);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return JNI_TRUE if the give column value is NULL, JNI_FALSE otherwise.
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jboolean IsNull(JNIEnv* env, jobject obj, jint column);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Moves the cursor to |pos|, returns new position.
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the returned position is not equal to |pos|, then the cursor points to
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the last row.
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jint MoveTo(JNIEnv* env, jobject obj, jint pos);
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Returns the type of column.
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  jint GetColumnType(JNIEnv* env, jobject obj, jint column);
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Called from Java to relase this object.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Destroy(JNIEnv* env, jobject obj);
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FRIEND_TEST_ALL_PREFIXES(SQLiteCursorTest, Run);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |column_names| is the column names of this cursor, the sequence of name
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // should match the sql query's projection name.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // |statement| is query's statement which bound the variables. This class
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // take the ownership of |statement|.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SQLiteCursor(const std::vector<std::string>& column_names,
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               history::AndroidStatement* statement,
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               AndroidHistoryProviderService* service,
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               FaviconService* favicon_service);
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~SQLiteCursor();
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // Destory SQLiteCursor object on UI thread. All cleanup need finish in UI
142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  // thread.
143868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  void DestroyOnUIThread();
144868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This method is for testing only.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void set_test_observer(TestObserver* test_observer) {
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    test_observer_ = test_observer;
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Get Favicon from history backend.
1510529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  bool GetFavicon(favicon_base::FaviconID id,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                  std::vector<unsigned char>* image_data);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void GetFaviconForIDInUIThread(
1550529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      favicon_base::FaviconID id,
156f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      const favicon_base::FaviconRawBitmapCallback& callback);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The callback function of FaviconService::GetLargestRawFaviconForID().
159f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  void OnFaviconData(const favicon_base::FaviconRawBitmapResult& bitmap_result);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The callback function of MoveTo().
16290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  void OnMoved(AndroidHistoryProviderService::Handle handle, int pos);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  JavaColumnType GetColumnTypeInternal(int column);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Runs the MoveStatement on UI thread.
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void RunMoveStatementOnUIThread(int pos);
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The current row position, '-1' means the position before the first one.
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int position_;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent event_;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The wrapped history::AndroidStatement.
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  history::AndroidStatement* statement_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Result set columns' name
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::vector<std::string> column_names_;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AndroidHistoryProviderService* service_;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconService* favicon_service_;
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Live on UI thread.
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<CancelableRequestConsumer> consumer_;
1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  scoped_ptr<base::CancelableTaskTracker> tracker_;
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The count of result rows.
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int count_;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The favicon image.
192f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  favicon_base::FaviconRawBitmapResult favicon_bitmap_result_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestObserver* test_observer_;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(SQLiteCursor);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif  // CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
200