sqlite_cursor.h revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#ifndef CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_ 6#define CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_ 7 8#include <jni.h> 9#include <vector> 10 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/string16.h" 16#include "base/synchronization/waitable_event.h" 17#include "chrome/browser/common/cancelable_request.h" 18#include "chrome/browser/favicon/favicon_service.h" 19#include "chrome/browser/history/android/android_history_provider_service.h" 20#include "chrome/browser/history/history_types.h" 21 22// This class is JNI implementation of 23// org.chromium.chrome.database.SqliteCursor, it uses the AndroidStatement to 24// iterate among the result rows. This is not thread safe, all methods should 25// be called from the same non-UI thread which typical is the Java thread. 26// 27// This class can not be in history namespace because the class name has to 28// match to the generated sqlite_cursor_jni.h. 29class SQLiteCursor { 30 public: 31 // Mapping to the column type definitions in java.sql.Types. 32 enum JavaColumnType { 33 BLOB = 2004, 34 LONG_VAR_CHAR = -1, 35 NULL_TYPE = 0, 36 NUMERIC = 2, 37 DOUBLE = 8, 38 }; 39 40 // This class is intended to be used only in unit tests. 41 // 42 // There are 2 threads in unit test, one is the UI thread, another is the DB 43 // thread, after the task posted into UI thread, the MessageLoop needs to run 44 // to execute the task. The OnPostMoveToTask() and the OnPostGetFaviconTask() 45 // give unit tests a chance to run the message loop before event_.Wait is 46 // invoked, The OnGetMoveToResult() and OnGetFaviconResult() is used to notify 47 // the test observer in the UI thread when the task's result comes back, it 48 // calls MessageLoop::Quit() to exit the loop, then the event.Wait() is 49 // called. Basically, Two threads are used to simulate 3 threads' behavior 50 // here. 51 // The whole observer design is only for test purpose and should only be used 52 // in unit test. 53 class TestObserver { 54 public: 55 TestObserver(); 56 57 // Notify the MoveTo task has been posted to UI thread. 58 virtual void OnPostMoveToTask() = 0; 59 // Notify the MoveTo result has been gotten in UI thread. 60 virtual void OnGetMoveToResult() = 0; 61 // Notify the GetFavicon task has been posted to UI thread. 62 virtual void OnPostGetFaviconTask() = 0; 63 // Notify the GetFavicon result has been gotten in UI thread. 64 virtual void OnGetFaviconResult() = 0; 65 66 protected: 67 virtual ~TestObserver(); 68 }; 69 70 // Returns org.chromium.chrome.SQLiteCursor java object by creating 71 // SQLitCursor native and java objects, then bind them together. 72 static base::android::ScopedJavaLocalRef<jobject> NewJavaSqliteCursor( 73 JNIEnv* env, 74 const std::vector<std::string>& column_names, 75 history::AndroidStatement* statement, 76 AndroidHistoryProviderService* service, 77 FaviconService* favicon_service); 78 79 static bool RegisterSqliteCursor(JNIEnv* env); 80 81 // JNI methods ----------------------------------------------------------- 82 83 // Returns the result row count. 84 jint GetCount(JNIEnv* env, jobject obj); 85 86 // Returns the result's columns' name. 87 base::android::ScopedJavaLocalRef<jobjectArray> GetColumnNames( 88 JNIEnv* env, 89 jobject obj); 90 91 // Returns the given column value as jstring. 92 base::android::ScopedJavaLocalRef<jstring> GetString(JNIEnv* env, 93 jobject obj, 94 jint column); 95 96 // Returns the given column value as jlong. 97 jlong GetLong(JNIEnv* env, jobject obj, jint column); 98 99 // Returns the given column value as int. 100 jint GetInt(JNIEnv* env, jobject obj, jint column); 101 102 // Returns the given column value as double. 103 jdouble GetDouble(JNIEnv* env, jobject obj, jint column); 104 105 // Returns the given column value as jbyteArray. 106 base::android::ScopedJavaLocalRef<jbyteArray> GetBlob(JNIEnv* env, 107 jobject obj, 108 jint column); 109 110 // Return JNI_TRUE if the give column value is NULL, JNI_FALSE otherwise. 111 jboolean IsNull(JNIEnv* env, jobject obj, jint column); 112 113 // Moves the cursor to |pos|, returns new position. 114 // If the returned position is not equal to |pos|, then the cursor points to 115 // the last row. 116 jint MoveTo(JNIEnv* env, jobject obj, jint pos); 117 118 // Returns the type of column. 119 jint GetColumnType(JNIEnv* env, jobject obj, jint column); 120 121 // Called from Java to relase this object. 122 void Destroy(JNIEnv* env, jobject obj); 123 124 private: 125 FRIEND_TEST_ALL_PREFIXES(SQLiteCursorTest, Run); 126 127 // |column_names| is the column names of this cursor, the sequence of name 128 // should match the sql query's projection name. 129 // |statement| is query's statement which bound the variables. This class 130 // take the ownership of |statement|. 131 SQLiteCursor(const std::vector<std::string>& column_names, 132 history::AndroidStatement* statement, 133 AndroidHistoryProviderService* service, 134 FaviconService* favicon_service); 135 136 virtual ~SQLiteCursor(); 137 138 // This method is for testing only. 139 void set_test_observer(TestObserver* test_observer) { 140 test_observer_ = test_observer; 141 } 142 143 // Get Favicon from history backend. 144 bool GetFavicon(history::FaviconID id, 145 std::vector<unsigned char>* image_data); 146 147 void GetFaviconForIDInUIThread( 148 history::FaviconID id, 149 CancelableRequestConsumerBase* consumer, 150 const FaviconService::FaviconRawCallback& callback); 151 152 // The Callback function of GetFavicon(). 153 void OnFaviconData(FaviconService::Handle handle, 154 const history::FaviconBitmapResult& bitmap_result); 155 156 // The callback function of MoveTo(). 157 void OnMoved(AndroidHistoryProviderService::Handle handle, 158 int pos); 159 160 // Used to cancel all request on the UI thread during shutdown. 161 void CancelAllRequests(base::WaitableEvent* finished); 162 163 JavaColumnType GetColumnTypeInternal(int column); 164 165 // Runs the MoveStatement on UI thread. 166 void RunMoveStatementOnUIThread(int pos); 167 168 // The current row position, '-1' means the position before the first one. 169 int position_; 170 171 base::WaitableEvent event_; 172 173 // The wrapped history::AndroidStatement. 174 history::AndroidStatement* statement_; 175 176 // Result set columns' name 177 const std::vector<std::string> column_names_; 178 179 AndroidHistoryProviderService* service_; 180 181 FaviconService* favicon_service_; 182 183 CancelableRequestConsumer consumer_; 184 185 // The count of result rows. 186 int count_; 187 188 // The favicon image. 189 history::FaviconBitmapResult favicon_bitmap_result_; 190 191 TestObserver* test_observer_; 192 193 DISALLOW_COPY_AND_ASSIGN(SQLiteCursor); 194}; 195 196#endif // CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_ 197