sqlite_cursor.h revision 0529e5d033099cbfc42635f6f6183833b09dff6e
14afc63c18f7d811f31dbd2e5d825ce9d10c93decAlexey Samsonov// Copyright (c) 2012 The Chromium Authors. All rights reserved.
24afc63c18f7d811f31dbd2e5d825ce9d10c93decAlexey Samsonov// Use of this source code is governed by a BSD-style license that can be
34afc63c18f7d811f31dbd2e5d825ce9d10c93decAlexey Samsonov// found in the LICENSE file.
4d668cd2ff37af5db33d21de9e809018ae74a99b7Alexey Samsonov
52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#ifndef CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
64afc63c18f7d811f31dbd2e5d825ce9d10c93decAlexey Samsonov#define CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
706f069aa9b3dc692457366a6882e7b5d5da84ec3Alexey Samsonov
82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <jni.h>
948ecaf475c7084125ec1985f0ad7efc1b4b8306eAlexey Samsonov#include <vector>
1006f069aa9b3dc692457366a6882e7b5d5da84ec3Alexey Samsonov
1106f069aa9b3dc692457366a6882e7b5d5da84ec3Alexey Samsonov#include "base/android/scoped_java_ref.h"
122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "base/basictypes.h"
132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include "base/gtest_prod_util.h"
1406f069aa9b3dc692457366a6882e7b5d5da84ec3Alexey Samsonov#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"
22
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.
27//
28// This class can not be in history namespace because the class name has to
29// match to the generated sqlite_cursor_jni.h.
30class SQLiteCursor {
31 public:
32  // Mapping to the column type definitions in java.sql.Types.
33  enum JavaColumnType {
34    BLOB = 2004,
35    LONG_VAR_CHAR = -1,
36    NULL_TYPE = 0,
37    NUMERIC = 2,
38    DOUBLE = 8,
39  };
40
41  // This class is intended to be used only in unit tests.
42  //
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
51  // here.
52  // The whole observer design is only for test purpose and should only be used
53  // in unit test.
54  class TestObserver {
55   public:
56    TestObserver();
57
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;
66
67   protected:
68    virtual ~TestObserver();
69  };
70
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(
74      JNIEnv* env,
75      const std::vector<std::string>& column_names,
76      history::AndroidStatement* statement,
77      AndroidHistoryProviderService* service,
78      FaviconService* favicon_service);
79
80  static bool RegisterSqliteCursor(JNIEnv* env);
81
82  // JNI methods -----------------------------------------------------------
83
84  // Returns the result row count.
85  jint GetCount(JNIEnv* env, jobject obj);
86
87  // Returns the result's columns' name.
88  base::android::ScopedJavaLocalRef<jobjectArray> GetColumnNames(
89      JNIEnv* env,
90      jobject obj);
91
92  // Returns the given column value as jstring.
93  base::android::ScopedJavaLocalRef<jstring> GetString(JNIEnv* env,
94                                                       jobject obj,
95                                                       jint column);
96
97  // Returns the given column value as jlong.
98  jlong GetLong(JNIEnv* env, jobject obj, jint column);
99
100  // Returns the given column value as int.
101  jint GetInt(JNIEnv* env, jobject obj, jint column);
102
103  // Returns the given column value as double.
104  jdouble GetDouble(JNIEnv* env, jobject obj, jint column);
105
106  // Returns the given column value as jbyteArray.
107  base::android::ScopedJavaLocalRef<jbyteArray> GetBlob(JNIEnv* env,
108                                                        jobject obj,
109                                                        jint column);
110
111  // Return JNI_TRUE if the give column value is NULL, JNI_FALSE otherwise.
112  jboolean IsNull(JNIEnv* env, jobject obj, jint column);
113
114  // Moves the cursor to |pos|, returns new position.
115  // If the returned position is not equal to |pos|, then the cursor points to
116  // the last row.
117  jint MoveTo(JNIEnv* env, jobject obj, jint pos);
118
119  // Returns the type of column.
120  jint GetColumnType(JNIEnv* env, jobject obj, jint column);
121
122  // Called from Java to relase this object.
123  void Destroy(JNIEnv* env, jobject obj);
124
125 private:
126  FRIEND_TEST_ALL_PREFIXES(SQLiteCursorTest, Run);
127
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);
136
137  virtual ~SQLiteCursor();
138
139  // Destory SQLiteCursor object on UI thread. All cleanup need finish in UI
140  // thread.
141  void DestroyOnUIThread();
142
143  // This method is for testing only.
144  void set_test_observer(TestObserver* test_observer) {
145    test_observer_ = test_observer;
146  }
147
148  // Get Favicon from history backend.
149  bool GetFavicon(favicon_base::FaviconID id,
150                  std::vector<unsigned char>* image_data);
151
152  void GetFaviconForIDInUIThread(
153      favicon_base::FaviconID id,
154      const FaviconService::FaviconRawCallback& callback);
155
156  // The callback function of FaviconService::GetLargestRawFaviconForID().
157  void OnFaviconData(const favicon_base::FaviconBitmapResult& bitmap_result);
158
159  // The callback function of MoveTo().
160  void OnMoved(AndroidHistoryProviderService::Handle handle, int pos);
161
162  JavaColumnType GetColumnTypeInternal(int column);
163
164  // Runs the MoveStatement on UI thread.
165  void RunMoveStatementOnUIThread(int pos);
166
167  // The current row position, '-1' means the position before the first one.
168  int position_;
169
170  base::WaitableEvent event_;
171
172  // The wrapped history::AndroidStatement.
173  history::AndroidStatement* statement_;
174
175  // Result set columns' name
176  const std::vector<std::string> column_names_;
177
178  AndroidHistoryProviderService* service_;
179
180  FaviconService* favicon_service_;
181
182  // Live on UI thread.
183  scoped_ptr<CancelableRequestConsumer> consumer_;
184  scoped_ptr<base::CancelableTaskTracker> tracker_;
185
186  // The count of result rows.
187  int count_;
188
189  // The favicon image.
190  favicon_base::FaviconBitmapResult favicon_bitmap_result_;
191
192  TestObserver* test_observer_;
193
194  DISALLOW_COPY_AND_ASSIGN(SQLiteCursor);
195};
196
197#endif  // CHROME_BROWSER_HISTORY_ANDROID_SQLITE_CURSOR_H_
198