2626import net .zetetic .database .sqlcipher .SQLiteDatabase .CursorFactory ;
2727import android .util .Log ;
2828import java .io .File ;
29+ import java .nio .ByteBuffer ;
30+ import java .nio .CharBuffer ;
31+ import java .nio .charset .Charset ;
2932
3033/**
3134 * A helper class to manage database creation and version management.
@@ -63,9 +66,11 @@ public abstract class SQLiteOpenHelper {
6366 private final int mMinimumSupportedVersion ;
6467
6568 private SQLiteDatabase mDatabase ;
69+ private byte [] mPassword ;
6670 private boolean mIsInitializing ;
6771 private boolean mEnableWriteAheadLogging ;
6872 private final DatabaseErrorHandler mErrorHandler ;
73+ private final SQLiteDatabaseHook mDatabaseHook ;
6974
7075 /**
7176 * Create a helper object to create, open, and/or manage a database.
@@ -131,13 +136,79 @@ public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int
131136 */
132137 public SQLiteOpenHelper (Context context , String name , CursorFactory factory , int version ,
133138 int minimumSupportedVersion , DatabaseErrorHandler errorHandler ) {
139+ this (context , name , new byte [0 ], factory , version , minimumSupportedVersion ,
140+ errorHandler , null );
141+ }
142+
143+ /**
144+ * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)}
145+ * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old
146+ * versions of this database that are no longer supported. If a database with older version that
147+ * minimumSupportedVersion is found, it is simply deleted and a new database is created with the
148+ * given name and version
149+ *
150+ * @param context to use to open or create the database
151+ * @param name the name of the database file, null for a temporary in-memory database
152+ * @param password for use with SQLCipher
153+ * @param factory to use for creating cursor objects, null for default
154+ * @param version the required version of the database
155+ * @param minimumSupportedVersion the minimum version that is supported to be upgraded to
156+ * {@code version} via {@link #onUpgrade}. If the current database version is lower
157+ * than this, database is simply deleted and recreated with the version passed in
158+ * {@code version}. {@link #onBeforeDelete} is called before deleting the database
159+ * when this happens. This is 0 by default.
160+ * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
161+ * corruption, or null to use the default error handler.
162+ * @param databaseHook for preKey and postKey events with SQLCipher.
163+ * @see #onBeforeDelete(SQLiteDatabase)
164+ * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)
165+ * @see #onUpgrade(SQLiteDatabase, int, int)
166+ * @hide
167+ */
168+ public SQLiteOpenHelper (Context context , String name , String password , CursorFactory factory ,
169+ int version , int minimumSupportedVersion ,
170+ DatabaseErrorHandler errorHandler , SQLiteDatabaseHook databaseHook ){
171+ this (context , name , getBytes (password ), factory , version , minimumSupportedVersion ,
172+ errorHandler , databaseHook );
173+ }
174+
175+ /**
176+ * Same as {@link #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)}
177+ * but also accepts an integer minimumSupportedVersion as a convenience for upgrading very old
178+ * versions of this database that are no longer supported. If a database with older version that
179+ * minimumSupportedVersion is found, it is simply deleted and a new database is created with the
180+ * given name and version
181+ *
182+ * @param context to use to open or create the database
183+ * @param name the name of the database file, null for a temporary in-memory database
184+ * @param password for use with SQLCipher
185+ * @param factory to use for creating cursor objects, null for default
186+ * @param version the required version of the database
187+ * @param minimumSupportedVersion the minimum version that is supported to be upgraded to
188+ * {@code version} via {@link #onUpgrade}. If the current database version is lower
189+ * than this, database is simply deleted and recreated with the version passed in
190+ * {@code version}. {@link #onBeforeDelete} is called before deleting the database
191+ * when this happens. This is 0 by default.
192+ * @param errorHandler the {@link DatabaseErrorHandler} to be used when sqlite reports database
193+ * corruption, or null to use the default error handler.
194+ * @param databaseHook for preKey and postKey events with SQLCipher.
195+ * @see #onBeforeDelete(SQLiteDatabase)
196+ * @see #SQLiteOpenHelper(Context, String, CursorFactory, int, DatabaseErrorHandler)
197+ * @see #onUpgrade(SQLiteDatabase, int, int)
198+ * @hide
199+ */
200+ public SQLiteOpenHelper (Context context , String name , byte [] password , CursorFactory factory ,
201+ int version , int minimumSupportedVersion ,
202+ DatabaseErrorHandler errorHandler , SQLiteDatabaseHook databaseHook ) {
134203 if (version < 1 ) throw new IllegalArgumentException ("Version must be >= 1, was " + version );
135204
136205 mContext = context ;
137206 mName = name ;
207+ mPassword = password ;
138208 mFactory = factory ;
139209 mNewVersion = version ;
140210 mErrorHandler = errorHandler ;
211+ mDatabaseHook = databaseHook ;
141212 mMinimumSupportedVersion = Math .max (0 , minimumSupportedVersion );
142213 }
143214
@@ -253,11 +324,11 @@ private SQLiteDatabase getDatabaseLocked(boolean writable) {
253324 try {
254325 if (DEBUG_STRICT_READONLY && !writable ) {
255326 final String path = mContext .getDatabasePath (mName ).getPath ();
256- db = SQLiteDatabase .openDatabase (path , mFactory ,
257- SQLiteDatabase .OPEN_READONLY , mErrorHandler );
327+ db = SQLiteDatabase .openDatabase (path , mPassword , mFactory ,
328+ SQLiteDatabase .OPEN_READONLY , mErrorHandler , mDatabaseHook );
258329 } else {
259330 db = SQLiteDatabase .openOrCreateDatabase (
260- mName , mFactory , mErrorHandler
331+ mName , mPassword , mFactory , mErrorHandler , mDatabaseHook
261332 );
262333 }
263334 } catch (SQLiteException ex ) {
@@ -267,8 +338,8 @@ private SQLiteDatabase getDatabaseLocked(boolean writable) {
267338 Log .e (TAG , "Couldn't open " + mName
268339 + " for writing (will try read-only):" , ex );
269340 final String path = mContext .getDatabasePath (mName ).getPath ();
270- db = SQLiteDatabase .openDatabase (path , mFactory ,
271- SQLiteDatabase .OPEN_READONLY , mErrorHandler );
341+ db = SQLiteDatabase .openDatabase (path , mPassword , mFactory ,
342+ SQLiteDatabase .OPEN_READONLY , mErrorHandler , mDatabaseHook );
272343 }
273344 }
274345
@@ -438,4 +509,13 @@ public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
438509 * @param db The database.
439510 */
440511 public void onOpen (SQLiteDatabase db ) {}
512+
513+ private static byte [] getBytes (String data ) {
514+ if (data == null || data .length () == 0 ) return new byte [0 ];
515+ CharBuffer charBuffer = CharBuffer .wrap (data );
516+ ByteBuffer byteBuffer = Charset .forName ("UTF-8" ).encode (charBuffer );
517+ byte [] result = new byte [byteBuffer .limit ()];
518+ byteBuffer .get (result );
519+ return result ;
520+ }
441521}
0 commit comments