Skip to content

Commit

Permalink
Switch to encrypted DatabaseManager
Browse files Browse the repository at this point in the history
  • Loading branch information
danilo-delbusso committed Mar 21, 2021
1 parent 833b358 commit abe77dc
Show file tree
Hide file tree
Showing 9 changed files with 53 additions and 45 deletions.
18 changes: 0 additions & 18 deletions app/debug/output-metadata.json

This file was deleted.

67 changes: 46 additions & 21 deletions app/src/main/java/com/prj/app/DatabaseManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
import android.annotation.SuppressLint;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.location.Location;
import android.net.wifi.ScanResult;
import android.util.Log;
Expand All @@ -13,17 +11,22 @@

import com.google.android.gms.maps.model.LatLng;

import net.sqlcipher.database.SQLiteDatabase;
import net.sqlcipher.database.SQLiteOpenHelper;

import org.json.JSONArray;
import org.json.JSONObject;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@SuppressLint("SimpleDateFormat")
@SuppressLint({"StaticFieldLeak", "SimpleDateFormat"})
public class DatabaseManager extends SQLiteOpenHelper {
private static final String SCAN_RESULT_TAB = "SCAN_RESULT_TAB";
private static final String COLUMN_ID = "ID";
Expand All @@ -32,40 +35,62 @@ public class DatabaseManager extends SQLiteOpenHelper {
private static final String SETTINGS_TAB = "SETTINGS_TAB";
private static final String LOCATION_TAB = "LOCATION_TAB";
private static final int COORDINATES_PRECISION = 5;
private static final String DB_PATH = "prj-app-db.db";
private static DatabaseManager instance;

private final Context context;

public DatabaseManager(@Nullable Context context) {
super(context, "prj-app-db.db", null, 1);
private DatabaseManager(@Nullable Context context) {
super(context, DB_PATH, null, 1);
this.context = context;
InitializeSQLCipher();
}

public static DatabaseManager getInstance(Context context) {
if (instance == null) {
instance = new DatabaseManager(context);
}
return instance;
}

@Override
public void onCreate(SQLiteDatabase db) {
String createTableStatement = String.format("CREATE TABLE %s (\n\t%s INTEGER PRIMARY KEY AUTOINCREMENT,\n\t%s TEXT NOT NULL\n)", SCAN_RESULT_TAB, COLUMN_ID, COLUMN_TIMESTAMP);

db.execSQL(createTableStatement);

createTableStatement = String.format("CREATE TABLE %s (\n\t ID INTEGER PRIMARY KEY AUTOINCREMENT,\n\t SCAN_RESULT_ID INTEGER NOT NULL,\n\t BSSID TEXT NOT NULL,\n\t DISTANCE NUMERIC NOT NULL\n);", BSSID_SCAN_TAB);

db.execSQL(createTableStatement);

createTableStatement = String.format("CREATE TABLE %s (\n\t NAME TEXT PRIMARY KEY,\n\t VALUE TEXT NOT NULL \n);", SETTINGS_TAB);

db.execSQL(createTableStatement);

createTableStatement = String.format("CREATE TABLE %s (\n\t bssid TEXT PRIMARY KEY,\n\t lat NUMBER NOT NULL, \n\t lng NUMBER NOT NULL \n);", LOCATION_TAB);
db.execSQL(createTableStatement);

String insertSettingsQuery = String.format("INSERT INTO %s (NAME, VALUE) VALUES ('SAVE_HOTSPOT_LOCATION', 0)", SETTINGS_TAB);
db.execSQL(insertSettingsQuery);
}

/**
* Initialise an encrypted SQLite database if it doesn't exist
*/
private void InitializeSQLCipher() {
try {
CryptoManager.generateDatabasePassword(context);
} catch (GeneralSecurityException | IOException e) {
e.printStackTrace();
}
SQLiteDatabase.loadLibs(context);
String databaseFile = context.getDatabasePath(DB_PATH).getPath();
SQLiteDatabase.openOrCreateDatabase(databaseFile, CryptoManager.getDatabasePassword(context), null);
}


@Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {

}

public void addLocationData(List<ScanResult> results, Location location) {
SQLiteDatabase readableDb = this.getReadableDatabase();
SQLiteDatabase writeableDb = this.getWritableDatabase();
SQLiteDatabase readableDb = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
SQLiteDatabase writeableDb = this.getWritableDatabase(CryptoManager.getDatabasePassword(context));

for (ScanResult result : results) {

Expand Down Expand Up @@ -100,7 +125,7 @@ public void addLocationData(List<ScanResult> results, Location location) {
}

public void deleteData() {
SQLiteDatabase db = this.getWritableDatabase();
SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context));
db.execSQL(String.format("DELETE FROM %s;", BSSID_SCAN_TAB));
db.execSQL(String.format("DELETE FROM %s;", SCAN_RESULT_TAB));
}
Expand All @@ -115,7 +140,7 @@ public void addScan(List<ScanResult> scanList) {
return;
}
String isoTimestamp = ZonedDateTime.now(ZoneOffset.UTC).format(DateTimeFormatter.ISO_INSTANT);
SQLiteDatabase db = this.getWritableDatabase(); //locking database when using writable
SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context)); //locking database when using writable
db.execSQL("INSERT INTO SCAN_RESULT_TAB (" + COLUMN_TIMESTAMP + ") VALUES ('" + isoTimestamp + "');"); //INSERT NEW SCAN RESULT ID AND TIMESTAMP
int lastScanResultId = getLastScanResultId(db);
StringBuilder queryString = new StringBuilder();
Expand Down Expand Up @@ -151,7 +176,7 @@ public int getLastScanResultId(SQLiteDatabase db) {

public List<String> getScanBSSIDs() {
ArrayList<String> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
String query = "SELECT DISTINCT B.BSSID\n" +
"FROM " + BSSID_SCAN_TAB + " B\n" +
" INNER JOIN " + SCAN_RESULT_TAB + " A\n" +
Expand All @@ -175,7 +200,7 @@ public List<String> getScanBSSIDs() {

public List<String[]> getRawScanData() {
ArrayList<String[]> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
String query = "SELECT B.BSSID, B.DISTANCE, A.TIMESTAMP \n" +
"FROM " + BSSID_SCAN_TAB + " B\n" +
" INNER JOIN " + SCAN_RESULT_TAB + " A\n" +
Expand All @@ -199,7 +224,7 @@ public List<String[]> getRawScanData() {

public JSONArray getRawLocationData() {
JSONArray results = new JSONArray();
SQLiteDatabase db = this.getReadableDatabase();
SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
String query = String.format("SELECT * FROM %s", LOCATION_TAB);
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
Expand All @@ -221,7 +246,7 @@ public JSONArray getRawLocationData() {

public List<Scan> getScanData() {
ArrayList<Scan> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
String query = "SELECT DISTINCT B.BSSID, B.DISTANCE, A.TIMESTAMP \n" +
"FROM " + BSSID_SCAN_TAB + " B\n" +
" INNER JOIN " + SCAN_RESULT_TAB + " A\n" +
Expand All @@ -248,13 +273,13 @@ public List<Scan> getScanData() {
public void setSaveHotspotLocation(boolean value) {
int valueToInsert = value ? 1 : 0;
String query = "UPDATE " + SETTINGS_TAB + " SET VALUE = " + value + " WHERE NAME = 'SAVE_HOTSPOT_LOCATION'";
SQLiteDatabase db = this.getWritableDatabase();
SQLiteDatabase db = this.getWritableDatabase(CryptoManager.getDatabasePassword(context));
db.execSQL(query);
}

public boolean canSaveHotspotLocation() {
ArrayList<Integer> results = new ArrayList<>();
SQLiteDatabase db = this.getReadableDatabase();
SQLiteDatabase db = this.getReadableDatabase(CryptoManager.getDatabasePassword(context));
String query = "SELECT VALUE FROM SETTINGS_TAB WHERE NAME = 'SAVE_HOTSPOT_LOCATION'";
Cursor cursor = db.rawQuery(query, null);
cursor.moveToFirst();
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/DummyUploadWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public DummyUploadWorker(

@Override
public @NotNull Result doWork() {
DatabaseManager databaseManager = new DatabaseManager(getApplicationContext());
DatabaseManager databaseManager = DatabaseManager.getInstance(getApplicationContext());
List<String[]> results = databaseManager.getRawScanData(); //get the actual data in order to have consistent request sizes
//create dummy data
for (String[] row : results) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/ExposureWorker.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public ExposureWorker(
public @NotNull Result doWork() {
// Do the work here--in this case, upload the images.
Log.d("wifi", "Starting Exposure Check");
BSSIDMatcher bssidMatcher = new BSSIDMatcher(new DatabaseManager(getApplicationContext()), null, getApplicationContext());
BSSIDMatcher bssidMatcher = new BSSIDMatcher(DatabaseManager.getInstance(getApplicationContext()), null, getApplicationContext());
bssidMatcher.getMatchingBSSIDs(); //this will take care of sending a notification
return Result.success();
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/SettingsActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Objects.requireNonNull(getSupportActionBar()).hide();
setContentView(R.layout.activity_settings);
databaseManager = new DatabaseManager(this);
databaseManager = DatabaseManager.getInstance(getApplicationContext());
bssidMatcher = new BSSIDMatcher(databaseManager,
findViewById(R.id.resultTextView),
this.getApplicationContext());
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/UploadDataActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ protected void onCreate(Bundle savedInstanceState) {

public void uploadScans(View view) {
toggleLoading();
DatabaseManager databaseManager = new DatabaseManager(getApplicationContext());
DatabaseManager databaseManager = DatabaseManager.getInstance(getApplicationContext());
boolean canUploadLocation = ((Switch) findViewById(R.id.uploadLocationDataSwitch)).isChecked();

JSONArray locationData = canUploadLocation ? databaseManager.getRawLocationData() : new JSONArray();
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/WifiScanner.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public void onReceive(Context c, Intent intent) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
context.registerReceiver(wifiScanReceiver, intentFilter);
databaseManager = new DatabaseManager(context);
databaseManager = DatabaseManager.getInstance(context.getApplicationContext());
}

public void startScan(Location location) {
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/com/prj/app/WifiScanningService.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public void onCreate() {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.intent = intent;
databaseManager = new DatabaseManager(getApplicationContext());
databaseManager = DatabaseManager.getInstance(getApplicationContext());
if (notification == null) {
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
Expand Down
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
<string name="upload_title">Upload All Scan Data</string>
<string name="upload_location">I also want to upload all my location data</string>
<string name="upload_button">Yes, I want to upload my data</string>
<string name="preference_file_key">com.prj.app.PREFERENCE_FILE_KEY</string>
</resources>

0 comments on commit abe77dc

Please sign in to comment.