1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
6 #define CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
11 #include "base/android/scoped_java_ref.h"
12 #include "base/basictypes.h"
13 #include "base/gtest_prod_util.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/strings/string16.h"
16 #include "base/synchronization/waitable_event.h"
17 #include "base/task/cancelable_task_tracker.h"
18 #include "chrome/browser/common/cancelable_request.h"
19 #include "chrome/browser/favicon/favicon_service.h"
20 #include "chrome/browser/history/android/android_history_provider_service.h"
21 #include "chrome/browser/history/history_types.h"
23 // This class is JNI implementation of
24 // org.chromium.chrome.database.SqliteCursor, it uses the AndroidStatement to
25 // iterate among the result rows. This is not thread safe, all methods should
26 // be called from the same non-UI thread which typical is the Java thread.
28 // This class can not be in history namespace because the class name has to
29 // match to the generated sqlite_cursor_jni.h.
32 // Mapping to the column type definitions in java.sql.Types.
41 // This class is intended to be used only in unit tests.
43 // There are 2 threads in unit test, one is the UI thread, another is the DB
44 // thread, after the task posted into UI thread, the MessageLoop needs to run
45 // to execute the task. The OnPostMoveToTask() and the OnPostGetFaviconTask()
46 // give unit tests a chance to run the message loop before event_.Wait is
47 // invoked, The OnGetMoveToResult() and OnGetFaviconResult() is used to notify
48 // the test observer in the UI thread when the task's result comes back, it
49 // calls MessageLoop::Quit() to exit the loop, then the event.Wait() is
50 // called. Basically, Two threads are used to simulate 3 threads' behavior
52 // The whole observer design is only for test purpose and should only be used
58 // Notify the MoveTo task has been posted to UI thread.
59 virtual void OnPostMoveToTask() = 0;
60 // Notify the MoveTo result has been gotten in UI thread.
61 virtual void OnGetMoveToResult() = 0;
62 // Notify the GetFavicon task has been posted to UI thread.
63 virtual void OnPostGetFaviconTask() = 0;
64 // Notify the GetFavicon result has been gotten in UI thread.
65 virtual void OnGetFaviconResult() = 0;
68 virtual ~TestObserver();
71 // Returns org.chromium.chrome.SQLiteCursor java object by creating
72 // SQLitCursor native and java objects, then bind them together.
73 static base::android::ScopedJavaLocalRef<jobject> NewJavaSqliteCursor(
75 const std::vector<std::string>& column_names,
76 history::AndroidStatement* statement,
77 AndroidHistoryProviderService* service,
78 FaviconService* favicon_service);
80 static bool RegisterSqliteCursor(JNIEnv* env);
82 // JNI methods -----------------------------------------------------------
84 // Returns the result row count.
85 jint GetCount(JNIEnv* env, jobject obj);
87 // Returns the result's columns' name.
88 base::android::ScopedJavaLocalRef<jobjectArray> GetColumnNames(
92 // Returns the given column value as jstring.
93 base::android::ScopedJavaLocalRef<jstring> GetString(JNIEnv* env,
97 // Returns the given column value as jlong.
98 jlong GetLong(JNIEnv* env, jobject obj, jint column);
100 // Returns the given column value as int.
101 jint GetInt(JNIEnv* env, jobject obj, jint column);
103 // Returns the given column value as double.
104 jdouble GetDouble(JNIEnv* env, jobject obj, jint column);
106 // Returns the given column value as jbyteArray.
107 base::android::ScopedJavaLocalRef<jbyteArray> GetBlob(JNIEnv* env,
111 // Return JNI_TRUE if the give column value is NULL, JNI_FALSE otherwise.
112 jboolean IsNull(JNIEnv* env, jobject obj, jint column);
114 // Moves the cursor to |pos|, returns new position.
115 // If the returned position is not equal to |pos|, then the cursor points to
117 jint MoveTo(JNIEnv* env, jobject obj, jint pos);
119 // Returns the type of column.
120 jint GetColumnType(JNIEnv* env, jobject obj, jint column);
122 // Called from Java to relase this object.
123 void Destroy(JNIEnv* env, jobject obj);
126 FRIEND_TEST_ALL_PREFIXES(SQLiteCursorTest, Run);
128 // |column_names| is the column names of this cursor, the sequence of name
129 // should match the sql query's projection name.
130 // |statement| is query's statement which bound the variables. This class
131 // take the ownership of |statement|.
132 SQLiteCursor(const std::vector<std::string>& column_names,
133 history::AndroidStatement* statement,
134 AndroidHistoryProviderService* service,
135 FaviconService* favicon_service);
137 virtual ~SQLiteCursor();
139 // Destory SQLiteCursor object on UI thread. All cleanup need finish in UI
141 void DestroyOnUIThread();
143 // This method is for testing only.
144 void set_test_observer(TestObserver* test_observer) {
145 test_observer_ = test_observer;
148 // Get Favicon from history backend.
149 bool GetFavicon(chrome::FaviconID id,
150 std::vector<unsigned char>* image_data);
152 void GetFaviconForIDInUIThread(
153 chrome::FaviconID id,
154 const FaviconService::FaviconRawCallback& callback);
156 // The callback function of FaviconService::GetLargestRawFaviconForID().
157 void OnFaviconData(const chrome::FaviconBitmapResult& bitmap_result);
159 // The callback function of MoveTo().
160 void OnMoved(AndroidHistoryProviderService::Handle handle, int pos);
162 JavaColumnType GetColumnTypeInternal(int column);
164 // Runs the MoveStatement on UI thread.
165 void RunMoveStatementOnUIThread(int pos);
167 // The current row position, '-1' means the position before the first one.
170 base::WaitableEvent event_;
172 // The wrapped history::AndroidStatement.
173 history::AndroidStatement* statement_;
175 // Result set columns' name
176 const std::vector<std::string> column_names_;
178 AndroidHistoryProviderService* service_;
180 FaviconService* favicon_service_;
182 // Live on UI thread.
183 scoped_ptr<CancelableRequestConsumer> consumer_;
184 scoped_ptr<base::CancelableTaskTracker> tracker_;
186 // The count of result rows.
189 // The favicon image.
190 chrome::FaviconBitmapResult favicon_bitmap_result_;
192 TestObserver* test_observer_;
194 DISALLOW_COPY_AND_ASSIGN(SQLiteCursor);
197 #endif // CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_