From 5e0ca10dae424d141170dab4d5ba8cc25eeec891 Mon Sep 17 00:00:00 2001 From: akwizgran <michael@briarproject.org> Date: Fri, 11 May 2018 09:19:34 +0100 Subject: [PATCH] Add logging to debug account setup. --- .../bramble/util/AndroidUtils.java | 60 ++++++++++++++++++- .../briarproject/bramble/util/IoUtils.java | 17 +++++- .../briar/android/AndroidDatabaseConfig.java | 32 +++++++++- .../controller/ConfigControllerImpl.java | 24 ++++++-- .../android/login/SetupControllerImpl.java | 11 +++- .../android/splash/SplashScreenActivity.java | 14 ++++- 6 files changed, 145 insertions(+), 13 deletions(-) diff --git a/bramble-android/src/main/java/org/briarproject/bramble/util/AndroidUtils.java b/bramble-android/src/main/java/org/briarproject/bramble/util/AndroidUtils.java index 15edba9c49..fe13a7106e 100644 --- a/bramble-android/src/main/java/org/briarproject/bramble/util/AndroidUtils.java +++ b/bramble-android/src/main/java/org/briarproject/bramble/util/AndroidUtils.java @@ -6,15 +6,22 @@ import android.os.Build; import android.provider.Settings; import java.io.File; +import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.List; +import java.util.Scanner; +import java.util.logging.Logger; import static android.content.Context.MODE_PRIVATE; +import static java.util.logging.Level.INFO; public class AndroidUtils { + private static final Logger LOG = + Logger.getLogger(AndroidUtils.class.getName()); + // Fake Bluetooth address returned by BluetoothAdapter on API 23 and later private static final String FAKE_BLUETOOTH_ADDRESS = "02:00:00:00:00:00"; @@ -51,17 +58,66 @@ public class AndroidUtils { && !address.equals(FAKE_BLUETOOTH_ADDRESS); } + public static void logDataDirContents(Context ctx) { + if (LOG.isLoggable(INFO)) { + LOG.info("Contents of data directory:"); + logFileOrDir(new File(ctx.getApplicationInfo().dataDir)); + } + } + + private static void logFileOrDir(File f) { + LOG.info(f.getAbsolutePath() + " " + f.length()); + if (f.isDirectory()) { + File[] children = f.listFiles(); + if (children == null) { + LOG.info("Could not list files in " + f.getAbsolutePath()); + } else { + for (File child : children) logFileOrDir(child); + } + } + } + + public static File getSharedPrefsFile(Context ctx, String name) { + File dataDir = new File(ctx.getApplicationInfo().dataDir); + File prefsDir = new File(dataDir, "shared_prefs"); + return new File(prefsDir, name + ".xml"); + } + + public static void logFileContents(File f) { + if (LOG.isLoggable(INFO)) { + LOG.info("Contents of " + f.getAbsolutePath() + ":"); + try { + Scanner s = new Scanner(f); + while (s.hasNextLine()) LOG.info(s.nextLine()); + s.close(); + } catch (FileNotFoundException e) { + LOG.info(f.getAbsolutePath() + " not found"); + } + } + } + public static void deleteAppData(Context ctx) { File dataDir = new File(ctx.getApplicationInfo().dataDir); + if (LOG.isLoggable(INFO)) + LOG.info("Deleting app data from " + dataDir.getAbsolutePath()); File[] children = dataDir.listFiles(); if (children != null) { for (File child : children) { - if (!child.getName().equals("lib")) + if (!child.getName().equals("lib")) { + if (LOG.isLoggable(INFO)) + LOG.info("Deleting " + child.getAbsolutePath()); IoUtils.deleteFileOrDir(child); + } } + } else if (LOG.isLoggable(INFO)) { + LOG.info("Could not list files in " + dataDir.getAbsolutePath()); } // Recreate the cache dir as some OpenGL drivers expect it to exist - new File(dataDir, "cache").mkdir(); + boolean recreated = new File(dataDir, "cache").mkdir(); + if (LOG.isLoggable(INFO)) { + if (recreated) LOG.info("Recreated cache dir"); + else LOG.info("Could not recreate cache dir"); + } } public static File getReportDir(Context ctx) { diff --git a/bramble-api/src/main/java/org/briarproject/bramble/util/IoUtils.java b/bramble-api/src/main/java/org/briarproject/bramble/util/IoUtils.java index 13b05d84ca..6e14576c7d 100644 --- a/bramble-api/src/main/java/org/briarproject/bramble/util/IoUtils.java +++ b/bramble-api/src/main/java/org/briarproject/bramble/util/IoUtils.java @@ -9,20 +9,33 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; +import java.util.logging.Logger; import javax.annotation.Nullable; +import static java.util.logging.Level.INFO; + @NotNullByDefault public class IoUtils { + private static final Logger LOG = Logger.getLogger(IoUtils.class.getName()); + public static void deleteFileOrDir(File f) { if (f.isFile()) { - f.delete(); + delete(f); } else if (f.isDirectory()) { File[] children = f.listFiles(); if (children != null) for (File child : children) deleteFileOrDir(child); - f.delete(); + delete(f); + } + } + + private static void delete(File f) { + boolean deleted = f.delete(); + if (LOG.isLoggable(INFO)) { + if (deleted) LOG.info("Deleted " + f.getAbsolutePath()); + else LOG.info("Could not delete " + f.getAbsolutePath()); } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidDatabaseConfig.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidDatabaseConfig.java index 3f98bd8cc9..2fe5df11ae 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidDatabaseConfig.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidDatabaseConfig.java @@ -5,12 +5,18 @@ import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import java.io.File; +import java.util.logging.Logger; import javax.annotation.Nullable; +import static java.util.logging.Level.INFO; + @NotNullByDefault class AndroidDatabaseConfig implements DatabaseConfig { + private static final Logger LOG = + Logger.getLogger(AndroidDatabaseConfig.class.getName()); + private final File dir; @Nullable @@ -25,35 +31,59 @@ class AndroidDatabaseConfig implements DatabaseConfig { @Override public boolean databaseExists() { // FIXME should not run on UiThread #620 - if (!dir.isDirectory()) return false; + if (!dir.isDirectory()) { + if (LOG.isLoggable(INFO)) + LOG.info(dir.getAbsolutePath() + " is not a directory"); + return false; + } File[] files = dir.listFiles(); + if (LOG.isLoggable(INFO)) { + if (files == null) { + LOG.info("Could not list files in " + dir.getAbsolutePath()); + } else { + LOG.info("Files in " + dir.getAbsolutePath() + ":"); + for (File f : files) LOG.info(f.getName()); + } + LOG.info("Database exists: " + (files != null && files.length > 0)); + } return files != null && files.length > 0; } @Override public File getDatabaseDirectory() { + File dir = this.dir; + if (LOG.isLoggable(INFO)) + LOG.info("Database directory: " + dir.getAbsolutePath()); return dir; } @Override public void setEncryptionKey(SecretKey key) { + LOG.info("Setting database key"); this.key = key; } @Override public void setLocalAuthorName(String nickname) { + LOG.info("Setting local author name"); this.nickname = nickname; } @Override @Nullable public String getLocalAuthorName() { + String nickname = this.nickname; + if (LOG.isLoggable(INFO)) + LOG.info("Local author name has been set: " + (nickname != null)); return nickname; } @Override @Nullable public SecretKey getEncryptionKey() { + SecretKey key = this.key; + if (LOG.isLoggable(INFO)) + LOG.info("Database key has been set: " + (key != null)); return key; } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/ConfigControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/ConfigControllerImpl.java index 3c19794441..5b0f7b46dd 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/controller/ConfigControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/ConfigControllerImpl.java @@ -7,12 +7,19 @@ import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; import org.briarproject.bramble.util.AndroidUtils; +import java.util.logging.Logger; + import javax.annotation.Nullable; import javax.inject.Inject; +import static java.util.logging.Level.INFO; + @NotNullByDefault public class ConfigControllerImpl implements ConfigController { + private static final Logger LOG = + Logger.getLogger(ConfigControllerImpl.class.getName()); + private static final String PREF_DB_KEY = "key"; private final SharedPreferences briarPrefs; @@ -23,17 +30,20 @@ public class ConfigControllerImpl implements ConfigController { DatabaseConfig databaseConfig) { this.briarPrefs = briarPrefs; this.databaseConfig = databaseConfig; - } @Override @Nullable public String getEncryptedDatabaseKey() { - return briarPrefs.getString(PREF_DB_KEY, null); + String key = briarPrefs.getString(PREF_DB_KEY, null); + if (LOG.isLoggable(INFO)) + LOG.info("Got database key from preferences: " + (key != null)); + return key; } @Override public void storeEncryptedDatabaseKey(String hex) { + LOG.info("Storing database key in preferences"); SharedPreferences.Editor editor = briarPrefs.edit(); editor.putString(PREF_DB_KEY, hex); editor.apply(); @@ -41,21 +51,27 @@ public class ConfigControllerImpl implements ConfigController { @Override public void deleteAccount(Context ctx) { + LOG.info("Deleting account"); SharedPreferences.Editor editor = briarPrefs.edit(); editor.clear(); editor.apply(); AndroidUtils.deleteAppData(ctx); + AndroidUtils.logDataDirContents(ctx); } @Override public boolean accountExists() { String hex = getEncryptedDatabaseKey(); - return hex != null && databaseConfig.databaseExists(); + boolean exists = hex != null && databaseConfig.databaseExists(); + if (LOG.isLoggable(INFO)) LOG.info("Account exists: " + exists); + return exists; } @Override public boolean accountSignedIn() { - return databaseConfig.getEncryptionKey() != null; + boolean signedIn = databaseConfig.getEncryptionKey() != null; + if (LOG.isLoggable(INFO)) LOG.info("Signed in: " + signedIn); + return signedIn; } } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java index a491aee7a7..6d12d55f16 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/login/SetupControllerImpl.java @@ -9,10 +9,12 @@ import org.briarproject.bramble.api.crypto.PasswordStrengthEstimator; import org.briarproject.bramble.api.crypto.SecretKey; import org.briarproject.bramble.api.db.DatabaseConfig; import org.briarproject.bramble.api.nullsafety.NotNullByDefault; +import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.briar.android.controller.handler.ResultHandler; import org.briarproject.briar.android.controller.handler.UiResultHandler; import java.util.concurrent.Executor; +import java.util.logging.Logger; import javax.inject.Inject; @@ -20,8 +22,11 @@ import javax.inject.Inject; public class SetupControllerImpl extends PasswordControllerImpl implements SetupController { + private static final Logger LOG = + Logger.getLogger(SetupControllerImpl.class.getName()); + @Nullable - private SetupActivity setupActivity; + private SetupActivity setupActivity; // TODO: Should be volatile @Inject SetupControllerImpl(SharedPreferences briarPrefs, @@ -91,11 +96,15 @@ public class SetupControllerImpl extends PasswordControllerImpl String password = setupActivity.getPassword(); if (password == null) throw new IllegalStateException(); cryptoExecutor.execute(() -> { + LOG.info("Creating account"); + AndroidUtils.logDataDirContents(setupActivity); databaseConfig.setLocalAuthorName(authorName); SecretKey key = crypto.generateSecretKey(); databaseConfig.setEncryptionKey(key); String hex = encryptDatabaseKey(key, password); storeEncryptedDatabaseKey(hex); + LOG.info("Created account"); + AndroidUtils.logDataDirContents(setupActivity); resultHandler.onResult(null); }); } diff --git a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java index f21f460aa1..fecce62510 100644 --- a/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java +++ b/briar-android/src/main/java/org/briarproject/briar/android/splash/SplashScreenActivity.java @@ -8,6 +8,7 @@ import android.support.v7.preference.PreferenceManager; import android.transition.Fade; import org.briarproject.bramble.api.system.AndroidExecutor; +import org.briarproject.bramble.util.AndroidUtils; import org.briarproject.briar.R; import org.briarproject.briar.android.activity.ActivityComponent; import org.briarproject.briar.android.activity.BaseActivity; @@ -44,9 +45,11 @@ public class SplashScreenActivity extends BaseActivity { setContentView(R.layout.splash); if (configController.accountSignedIn()) { + LOG.info("Already signed in, not showing splash screen"); startActivity(new Intent(this, OpenDatabaseActivity.class)); finish(); } else { + LOG.info("Showing splash screen"); new Handler().postDelayed(() -> { startNextActivity(); supportFinishAfterTransition(); @@ -64,9 +67,12 @@ public class SplashScreenActivity extends BaseActivity { LOG.info("Expired"); startActivity(new Intent(this, ExpiredActivity.class)); } else { + AndroidUtils.logDataDirContents(this); if (configController.accountExists()) { + LOG.info("Account exists"); startActivity(new Intent(this, OpenDatabaseActivity.class)); } else { + LOG.info("Account does not exist"); configController.deleteAccount(this); startActivity(new Intent(this, SetupActivity.class)); } @@ -74,8 +80,10 @@ public class SplashScreenActivity extends BaseActivity { } private void setPreferencesDefaults() { - androidExecutor.runOnBackgroundThread(() -> - PreferenceManager.setDefaultValues(SplashScreenActivity.this, - R.xml.panic_preferences, false)); + androidExecutor.runOnBackgroundThread(() -> { + PreferenceManager.setDefaultValues(SplashScreenActivity.this, + R.xml.panic_preferences, false); + LOG.info("Finished setting panic preference defaults"); + }); } } -- GitLab