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