diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java index 707c4c80f5..511ca9757d 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBApplication.java @@ -48,7 +48,6 @@ import android.os.Bundle; import android.os.StrictMode; import android.preference.PreferenceManager; import android.provider.ContactsContract.PhoneLookup; -import android.util.Log; import android.util.TypedValue; import android.view.Window; import android.view.WindowManager; @@ -60,17 +59,16 @@ import androidx.core.app.NotificationCompat; import androidx.core.content.ContextCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; -import org.slf4j.LoggerFactory; import androidx.lifecycle.ProcessLifecycleOwner; -import java.io.File; -import java.io.IOException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; -import ch.qos.logback.core.spi.LifeCycle; import nodomain.freeyourgadget.gadgetbridge.activities.ControlCenterv2; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; @@ -87,7 +85,6 @@ import nodomain.freeyourgadget.gadgetbridge.prefs.GBPrefsMigrator; import nodomain.freeyourgadget.gadgetbridge.service.NotificationCollectorMonitorService; import nodomain.freeyourgadget.gadgetbridge.util.AndroidUtils; import nodomain.freeyourgadget.gadgetbridge.util.BondingUtil; -import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.GBPrefs; import nodomain.freeyourgadget.gadgetbridge.util.InternetHelperSingleton; @@ -103,9 +100,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.preferences.DevicePrefs; * logging and DB access. */ public class GBApplication extends Application { - // Since this class must not log to slf4j, we use plain android.util.Log - private static final String TAG = "GBApplication"; - private static volatile ShutdownHook SHUTDOWN_HOOK; + private static final Logger LOG = LoggerFactory.getLogger(GBApplication.class); private static GBApplication context; private static DeviceService deviceService; @@ -128,17 +123,6 @@ public class GBApplication extends Application { private static GBApplication app; - private static final Logging logging = new Logging() { - @Override - protected String createLogDirectory() throws IOException { - if (GBEnvironment.env().isLocalTest()) { - return System.getProperty(Logging.PROP_LOGFILES_DIR); - } else { - File dir = FileUtils.getExternalFilesDir(); - return dir.getAbsolutePath(); - } - } - }; private static Locale language; private DeviceManager deviceManager; @@ -146,25 +130,8 @@ public class GBApplication extends Application { private OpenTracksContentObserver openTracksObserver; - /// flush the log buffer and stop file logging - private static final class ShutdownHook implements Runnable { - @Override - public void run() { - try { - logging.stopFileLogger(); - } catch (Throwable ignored) { - } - - try { - LifeCycle lifeCycle = (LifeCycle) LoggerFactory.getILoggerFactory(); - lifeCycle.stop(); - } catch (Throwable ignored) { - } - } - } - public static void quit() { - GB.log("Quitting Gadgetbridge...", GB.INFO, null); + LOG.info("Quitting Gadgetbridge..."); BondingUtil.StopObservingAll(getContext()); Intent quitIntent = new Intent(GBApplication.ACTION_QUIT); LocalBroadcastManager.getInstance(context).sendBroadcast(quitIntent); @@ -174,7 +141,7 @@ public class GBApplication extends Application { } public static void restart() { - GB.log("Restarting Gadgetbridge...", GB.INFO, null); + LOG.info("Restarting Gadgetbridge..."); BondingUtil.StopObservingAll(getContext()); final Intent quitIntent = new Intent(GBApplication.ACTION_QUIT); LocalBroadcastManager.getInstance(context).sendBroadcast(quitIntent); @@ -244,10 +211,6 @@ public class GBApplication extends Application { } } - public static Logging getLogging() { - return logging; - } - protected DeviceService createDeviceService() { return new GBDeviceService(this); } @@ -274,9 +237,7 @@ public class GBApplication extends Application { GBDatabaseManager.setupDatabase(this); } - // don't do anything here before we set up logging, otherwise - // slf4j may be implicitly initialized before we properly configured it. - setupLogging(isFileLoggingEnabled()); + Logging.getInstance().initialize(prefs.getBoolean("log_to_file", false)); migratePrefsIfNeeded(); @@ -324,7 +285,7 @@ public class GBApplication extends Application { if (!prefs.getBoolean("prefs_key_enable_deprecated_notificationcollectormonitor", false)) { return; } - Log.i(TAG, "Starting the deprecated NotificationCollectorMonitorService foreground service."); + LOG.info("Starting the deprecated NotificationCollectorMonitorService foreground service."); try { //the following will ensure the notification manager is kept alive Intent serviceIntent = new Intent(context, NotificationCollectorMonitorService.class); @@ -379,40 +340,11 @@ public class GBApplication extends Application { return false; } - public static void setupLogging(boolean enabled) { - logging.setupLogging(enabled); - - // prepare for log shutdown - if(SHUTDOWN_HOOK == null) { - //noinspection NonThreadSafeLazyInitialization - SHUTDOWN_HOOK = new ShutdownHook(); - Thread thread = new Thread(SHUTDOWN_HOOK, "shutdownHook"); - Runtime runtime = Runtime.getRuntime(); - runtime.addShutdownHook(thread); - } - } - - public static String getLogPath() { - String path = logging.getLogPath(); - if (path == null) { - // file logging is currently disabled but there still might be an old logfile - try { - path = logging.createLogDirectory() + File.separator + "gadgetbridge.log"; - } catch (Exception ignored) { - } - } - return path; - } - private void setupExceptionHandler(final boolean notifyOnCrash) { final GBExceptionHandler handler = new GBExceptionHandler(Thread.getDefaultUncaughtExceptionHandler(), notifyOnCrash); Thread.setDefaultUncaughtExceptionHandler(handler); } - public static boolean isFileLoggingEnabled() { - return prefs.getBoolean("log_to_file", false); - } - public static boolean minimizeNotification() { return prefs.getBoolean("minimize_priority", false); } @@ -536,7 +468,7 @@ public class GBApplication extends Application { public static boolean appIsNotifBlacklisted(String packageName) { if (apps_notification_blacklist == null) { - GB.log("appIsNotifBlacklisted: apps_notification_blacklist is null!", GB.INFO, null); + LOG.info("appIsNotifBlacklisted: apps_notification_blacklist is null!"); } return apps_notification_blacklist != null && apps_notification_blacklist.contains(packageName); } @@ -547,22 +479,22 @@ public class GBApplication extends Application { public static void setAppsNotifBlackList(Set packageNames, SharedPreferences.Editor editor) { if (packageNames == null) { - GB.log("Set null apps_notification_blacklist", GB.INFO, null); + LOG.info("Set null apps_notification_blacklist"); apps_notification_blacklist = new HashSet<>(); } else { apps_notification_blacklist = new HashSet<>(packageNames); } - GB.log("New apps_notification_blacklist has " + apps_notification_blacklist.size() + " entries", GB.INFO, null); + LOG.info("New apps_notification_blacklist has {} entries", apps_notification_blacklist.size()); saveAppsNotifBlackList(editor); } private static void loadAppsNotifBlackList() { - GB.log("Loading apps_notification_blacklist", GB.INFO, null); + LOG.info("Loading apps_notification_blacklist"); apps_notification_blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.PACKAGE_BLACKLIST, null); // lgtm [java/abstract-to-concrete-cast] if (apps_notification_blacklist == null) { apps_notification_blacklist = new HashSet<>(); } - GB.log("Loaded apps_notification_blacklist has " + apps_notification_blacklist.size() + " entries", GB.INFO, null); + LOG.info("Loaded apps_notification_blacklist has {} entries", apps_notification_blacklist.size()); } private static void saveAppsNotifBlackList() { @@ -570,7 +502,7 @@ public class GBApplication extends Application { } private static void saveAppsNotifBlackList(SharedPreferences.Editor editor) { - GB.log("Saving apps_notification_blacklist with " + apps_notification_blacklist.size() + " entries", GB.INFO, null); + LOG.info("Saving apps_notification_blacklist with {} entries", apps_notification_blacklist.size()); if (apps_notification_blacklist.isEmpty()) { editor.putStringSet(GBPrefs.PACKAGE_BLACKLIST, null); } else { @@ -586,7 +518,7 @@ public class GBApplication extends Application { } public static synchronized void removeFromAppsNotifBlacklist(String packageName) { - GB.log("Removing from apps_notification_blacklist: " + packageName, GB.INFO, null); + LOG.info("Removing from apps_notification_blacklist: {}", packageName); apps_notification_blacklist.remove(packageName); saveAppsNotifBlackList(); } @@ -595,7 +527,7 @@ public class GBApplication extends Application { public static boolean appIsPebbleBlacklisted(String sender) { if (apps_pebblemsg_blacklist == null) { - GB.log("appIsPebbleBlacklisted: apps_pebblemsg_blacklist is null!", GB.INFO, null); + LOG.info("appIsPebbleBlacklisted: apps_pebblemsg_blacklist is null!"); } return apps_pebblemsg_blacklist != null && apps_pebblemsg_blacklist.contains(sender); } @@ -606,22 +538,22 @@ public class GBApplication extends Application { public static void setAppsPebbleBlackList(Set packageNames, SharedPreferences.Editor editor) { if (packageNames == null) { - GB.log("Set null apps_pebblemsg_blacklist", GB.INFO, null); + LOG.info("Set null apps_pebblemsg_blacklist"); apps_pebblemsg_blacklist = new HashSet<>(); } else { apps_pebblemsg_blacklist = new HashSet<>(packageNames); } - GB.log("New apps_pebblemsg_blacklist has " + apps_pebblemsg_blacklist.size() + " entries", GB.INFO, null); + LOG.info("New apps_pebblemsg_blacklist has {} entries", apps_pebblemsg_blacklist.size()); saveAppsPebbleBlackList(editor); } private static void loadAppsPebbleBlackList() { - GB.log("Loading apps_pebblemsg_blacklist", GB.INFO, null); + LOG.info("Loading apps_pebblemsg_blacklist"); apps_pebblemsg_blacklist = (HashSet) sharedPrefs.getStringSet(GBPrefs.PACKAGE_PEBBLEMSG_BLACKLIST, null); // lgtm [java/abstract-to-concrete-cast] if (apps_pebblemsg_blacklist == null) { apps_pebblemsg_blacklist = new HashSet<>(); } - GB.log("Loaded apps_pebblemsg_blacklist has " + apps_pebblemsg_blacklist.size() + " entries", GB.INFO, null); + LOG.info("Loaded apps_pebblemsg_blacklist has {} entries", apps_pebblemsg_blacklist.size()); } private static void saveAppsPebbleBlackList() { @@ -629,7 +561,7 @@ public class GBApplication extends Application { } private static void saveAppsPebbleBlackList(SharedPreferences.Editor editor) { - GB.log("Saving apps_pebblemsg_blacklist with " + apps_pebblemsg_blacklist.size() + " entries", GB.INFO, null); + LOG.info("Saving apps_pebblemsg_blacklist with {} entries", apps_pebblemsg_blacklist.size()); if (apps_pebblemsg_blacklist.isEmpty()) { editor.putStringSet(GBPrefs.PACKAGE_PEBBLEMSG_BLACKLIST, null); } else { @@ -645,7 +577,7 @@ public class GBApplication extends Application { } public static synchronized void removeFromAppsPebbleBlacklist(String packageName) { - GB.log("Removing from apps_pebblemsg_blacklist: " + packageName, GB.INFO, null); + LOG.info("Removing from apps_pebblemsg_blacklist: {}", packageName); apps_pebblemsg_blacklist.remove(packageNameToPebbleMsgSender(packageName)); saveAppsPebbleBlackList(); } @@ -802,7 +734,7 @@ public class GBApplication extends Application { try { return getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA).versionName; } catch (PackageManager.NameNotFoundException e) { - GB.log("Unable to determine Gadgetbridge's version", GB.WARN, e); + LOG.warn("Unable to determine Gadgetbridge's version", e); return "0.0.0"; } } @@ -813,7 +745,7 @@ public class GBApplication extends Application { PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_META_DATA); return String.format("%s %s", appInfo.name, packageInfo.versionName); } catch (PackageManager.NameNotFoundException e) { - GB.log("Unable to determine Gadgetbridge's name/version", GB.WARN, e); + LOG.warn("Unable to determine Gadgetbridge's name/version", e); return "Gadgetbridge"; } } @@ -831,7 +763,7 @@ public class GBApplication extends Application { public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { boolean preventScreenshots = getPrefs().getBoolean(GBPrefs.BLOCK_SCREENSHOTS, false); if (preventScreenshots) { - GB.log("set FLAG_SECURE for " + activity.getLocalClassName(), GB.DEBUG, null); + LOG.debug("set FLAG_SECURE for {}", activity.getLocalClassName()); Window window = activity.getWindow(); window.setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabase.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabase.java index a075993192..66a6fc61c7 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabase.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabase.java @@ -3,7 +3,9 @@ package nodomain.freeyourgadget.gadgetbridge; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.IOException; @@ -19,7 +21,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; * This class is NOT thread-safe, all calls should be guarded by the upstream write lock. */ public class GBDatabase { - private static final String TAG = "GBDatabase"; + private static final Logger LOG = LoggerFactory.getLogger(GBDatabase.class); + public static final String DATABASE_NAME = "Gadgetbridge"; private DaoMaster daoMaster = null; @@ -40,25 +43,25 @@ public class GBDatabase { void closeDatabase() { if (session == null) { - Log.w(TAG, "Database was already closed"); + LOG.warn("Database was already closed"); return; } - Log.d(TAG, "Trying to close database from " + Thread.currentThread().getName()); + LOG.debug("Trying to close database"); session.clear(); session.getDatabase().close(); session = null; daoMaster = null; helper = null; - Log.d(TAG, "Database closed"); + LOG.info("Database closed"); } void setupDatabase(final Context context) { if (session != null) { - Log.w(TAG, "Database already setup"); + LOG.warn("Database already setup"); return; } - Log.i(TAG, "Setting up database from " + Thread.currentThread().getName()); + LOG.debug("Setting up database"); if (GBEnvironment.env().isTest()) { helper = new DaoMaster.DevOpenHelper(context, null, null); @@ -71,7 +74,7 @@ public class GBDatabase { if (session == null) { throw new RuntimeException("Unable to create database session"); } - Log.d(TAG, "Database setup finished"); + LOG.info("Database setup finished"); } void importDB(final InputStream inputStream) throws IllegalStateException, IOException { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabaseManager.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabaseManager.java index ec0cdc4dff..feaf2ae660 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabaseManager.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBDatabaseManager.java @@ -1,7 +1,9 @@ package nodomain.freeyourgadget.gadgetbridge; import android.content.Context; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.File; import java.io.FileInputStream; @@ -15,7 +17,7 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.database.DBHelper; public class GBDatabaseManager { - private static final String TAG = "GBDatabaseManager"; + private static final Logger LOG = LoggerFactory.getLogger(GBDatabaseManager.class); private static final ReentrantReadWriteLock DB_LOCK = new ReentrantReadWriteLock(true); private static final GBDatabase GB_DATABASE = new GBDatabase(); @@ -24,7 +26,7 @@ public class GBDatabaseManager { } public static void closeDatabase() { - Log.v(TAG, "Trying to close database from " + Thread.currentThread().getName()); + LOG.trace("Trying to close database"); DB_LOCK.writeLock().lock(); try { GB_DATABASE.closeDatabase(); @@ -34,7 +36,7 @@ public class GBDatabaseManager { } public static void setupDatabase(final Context context) { - Log.v(TAG, "Setting up database from " + Thread.currentThread().getName()); + LOG.trace("Setting up database"); DB_LOCK.writeLock().lock(); try { GB_DATABASE.setupDatabase(context); @@ -56,26 +58,26 @@ public class GBDatabaseManager { */ public static DBHandler acquireWrite() throws GBException { try { - Log.v(TAG, "Trying to acquire write lock from " + Thread.currentThread().getName()); + LOG.trace("Trying to acquire write lock"); if (DB_LOCK.writeLock().tryLock(30, TimeUnit.SECONDS)) { - Log.v(TAG, "Acquired write lock from " + Thread.currentThread().getName()); + LOG.trace("Acquired write lock"); return new LockHandler(DB_LOCK.writeLock(), GB_DATABASE.getDaoMaster(), GB_DATABASE.getSession()); } } catch (final InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for DB lock"); + LOG.error("Interrupted while waiting for write DB lock", e); } throw new GBException("Failed to acquire database write lock"); } public static DBHandler acquireReadOnly() throws GBException { try { - Log.v(TAG, "Trying to acquire read lock from " + Thread.currentThread().getName()); + LOG.trace("Trying to acquire read lock"); if (DB_LOCK.readLock().tryLock(30, TimeUnit.SECONDS)) { - Log.v(TAG, "Acquired read lock from " + Thread.currentThread().getName()); + LOG.trace("Acquired read lock"); return new LockHandler(DB_LOCK.readLock(), GB_DATABASE.getDaoMaster(), GB_DATABASE.getSession()); } } catch (final InterruptedException e) { - Log.e(TAG, "Interrupted while waiting for DB lock"); + LOG.error("Interrupted while waiting for read DB lock", e); } throw new GBException("Failed to acquire database read lock"); } @@ -86,7 +88,7 @@ public class GBDatabaseManager { * @return true on successful deletion */ public static boolean deleteActivityDatabase(final Context context) { - Log.v(TAG, "Deleting activity database from " + Thread.currentThread().getName()); + LOG.trace("Deleting activity database"); DB_LOCK.writeLock().lock(); try { @@ -101,7 +103,7 @@ public class GBDatabaseManager { } public static void exportDB(final File destFile) throws IOException { - Log.v(TAG, "Exporting database to file from " + Thread.currentThread().getName()); + LOG.trace("Exporting database to file"); DB_LOCK.writeLock().lock(); try { @@ -112,7 +114,7 @@ public class GBDatabaseManager { } public static void exportDB(final OutputStream dest) throws IOException { - Log.v(TAG, "Exporting database to OutputStream from " + Thread.currentThread().getName()); + LOG.trace("Exporting database to OutputStream"); DB_LOCK.writeLock().lock(); try { @@ -128,7 +130,7 @@ public class GBDatabaseManager { * @return true on successful deletion */ public static boolean deleteOldActivityDatabase(final Context context) { - Log.v(TAG, "Deleting old activity database from " + Thread.currentThread().getName()); + LOG.trace("Deleting old activity database"); final DBHelper dbHelper = new DBHelper(context); boolean result = true; @@ -143,7 +145,7 @@ public class GBDatabaseManager { } public static void importDB(final InputStream inputStream) throws IllegalStateException, IOException { - Log.v(TAG, "Importing database from " + Thread.currentThread().getName()); + LOG.trace("Importing database"); DB_LOCK.writeLock().lock(); try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBExceptionHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBExceptionHandler.java index 3076a3bce0..b2e150e44c 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBExceptionHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/GBExceptionHandler.java @@ -39,6 +39,7 @@ import nodomain.freeyourgadget.gadgetbridge.util.GB; /** * Catches otherwise uncaught exceptions, logs them and terminates the app. */ +@SuppressWarnings("ClassCanBeRecord") public class GBExceptionHandler implements Thread.UncaughtExceptionHandler { private static final Logger LOG = LoggerFactory.getLogger(GBExceptionHandler.class); private final Thread.UncaughtExceptionHandler mDelegate; @@ -50,7 +51,7 @@ public class GBExceptionHandler implements Thread.UncaughtExceptionHandler { } /// Log and notify the unhandled exception - /// Flushing and closing the log is handled by {@link GBApplication.ShutdownHook} + /// Flushing and closing the log is handled by {@link Logging} shutdown hook @Override public void uncaughtException(@NonNull Thread thread, @NonNull Throwable ex) { // This method is only called if something is seriously wrong so be very generous diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java index dccb5fd9f9..a1391e2b0f 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/LockHandler.java @@ -17,7 +17,9 @@ package nodomain.freeyourgadget.gadgetbridge; import android.database.sqlite.SQLiteDatabase; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.concurrent.locks.Lock; @@ -29,7 +31,7 @@ import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; * Provides low-level access to the database. */ public class LockHandler implements DBHandler { - private static final String TAG = "LockHandler"; + private static final Logger LOG = LoggerFactory.getLogger(LockHandler.class); private final Lock lock; @@ -55,11 +57,11 @@ public class LockHandler implements DBHandler { @Override public void close() { if (closed) { - Log.w(TAG, lock.getClass().getSimpleName() + " was already closed (" + Thread.currentThread().getName() + ")"); + LOG.warn("{} was already closed", lock.getClass().getSimpleName()); return; } closed = true; - Log.d(TAG, "Releasing " + lock.getClass().getSimpleName() + " from " + Thread.currentThread().getName()); + LOG.trace("Releasing {}", lock.getClass().getSimpleName()); lock.unlock(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java index d6cc65987b..dab91df498 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/Logging.java @@ -18,10 +18,10 @@ package nodomain.freeyourgadget.gadgetbridge; import android.os.Build; -import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -36,19 +36,39 @@ import ch.qos.logback.core.Appender; import ch.qos.logback.core.FileAppender; import ch.qos.logback.core.rolling.RollingFileAppender; import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy; +import ch.qos.logback.core.spi.LifeCycle; import ch.qos.logback.core.util.FileSize; import ch.qos.logback.core.util.StatusPrinter; -import nodomain.freeyourgadget.gadgetbridge.util.GB; -import nodomain.freeyourgadget.gadgetbridge.BuildConfig; +import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; -public abstract class Logging { - // Only used for tests - public static final String PROP_LOGFILES_DIR = "GB_LOGFILES_DIR"; +public class Logging { + private static final Logger LOG = LoggerFactory.getLogger(Logging.class); + + private static final Logging INSTANCE = new Logging(); + + private Logging() { + } private String logDirectory; private FileAppender fileLogger; + private boolean initialized = false; - public void setupLogging(boolean enable) { + public static Logging getInstance() { + return INSTANCE; + } + + public void initialize(final boolean enable) { + setFileLoggingEnabled(enable); + // prepare for log shutdown + if (!initialized) { + final Thread thread = new Thread(this::shutdown, "shutdownHook"); + final Runtime runtime = Runtime.getRuntime(); + runtime.addShutdownHook(thread); + initialized = true; + } + } + + public void setFileLoggingEnabled(final boolean enable) { try { if (!isFileLoggerInitialized()) { init(); @@ -58,29 +78,43 @@ public abstract class Logging { } else { stopFileLogger(); } - getLogger().info("Gadgetbridge version: {}-{} {} {}", BuildConfig.VERSION_NAME, + LOG.info("Gadgetbridge version: {}-{} {} {}", BuildConfig.VERSION_NAME, BuildConfig.GIT_HASH_SHORT, BuildConfig.FLAVOR, BuildConfig.BUILD_TYPE); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.BAKLAVA) { - getLogger().info( + LOG.info( "Android: SDK_INT={} SECURITY_PATCH={}", Build.VERSION.SDK_INT, Build.VERSION.SECURITY_PATCH ); } else { - getLogger().info( + LOG.info( "Android: SDK_INT={} SDK_INT_FULL={} SECURITY_PATCH={}", Build.VERSION.SDK_INT, Build.VERSION.SDK_INT_FULL, Build.VERSION.SECURITY_PATCH ); } - } catch (Exception ex) { - Log.e("GBApplication", "External files dir not available, cannot log to file", ex); + } catch (final Exception ex) { + LOG.error("External files dir not available, cannot log to file", ex); stopFileLogger(); } } + /// flush the log buffer and stop file logging + public void shutdown() { + try { + stopFileLogger(); + } catch (Throwable ignored) { + } + + try { + LifeCycle lifeCycle = (LifeCycle) LoggerFactory.getILoggerFactory(); + lifeCycle.stop(); + } catch (Throwable ignored) { + } + } + @Nullable public String getLogPath() { if (fileLogger != null) @@ -89,9 +123,12 @@ public abstract class Logging { return null; } - public void setImmediateFlush(final boolean immediateFlush) { - if (fileLogger != null) { + public void flush() { + if (fileLogger != null && !fileLogger.isImmediateFlush()) { fileLogger.setImmediateFlush(true); + // Write something so it's actually flushed + LOG.debug("Flushing logs"); + fileLogger.setImmediateFlush(false); } } @@ -107,38 +144,36 @@ public abstract class Logging { // Logger logger = LoggerFactory.getLogger(Logging.class); } - protected abstract String createLogDirectory() throws IOException; + protected String createLogDirectory() throws IOException { + return FileUtils.getExternalFilesDir().getAbsolutePath(); + } - protected void init() throws IOException { - Log.i("GBApplication", "Initializing logging"); + private void init() throws IOException { + LOG.debug("Initializing logging"); logDirectory = createLogDirectory(); if (logDirectory == null) { throw new IllegalArgumentException("log directory must not be null"); } } - private Logger getLogger() { - return LoggerFactory.getLogger(Logging.class); - } - private void startFileLogger() { if (fileLogger != null) { - Log.w("GBApplication", "Logger already started"); + LOG.warn("Logger already started"); return; } if (logDirectory == null) { - Log.e("GBApplication", "Can't start file logging without a log directory"); + LOG.error("Can't start file logging without a log directory"); return; } - final FileAppender fileAppender = createFileAppender(logDirectory); + final FileAppender fileAppender = createFileAppender(logDirectory); fileAppender.start(); attachLogger(fileAppender); fileLogger = fileAppender; } - void stopFileLogger() { + public void stopFileLogger() { if (fileLogger == null) { return; } @@ -152,34 +187,35 @@ public abstract class Logging { fileLogger = null; } - private void attachLogger(Appender logger) { + private static void attachLogger(final Appender logger) { try { ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); if (!root.isAttached(logger)) { root.addAppender(logger); } - } catch (Throwable ex) { - Log.e("GBApplication", "Error attaching logger appender", ex); + } catch (final Throwable e) { + LOG.error("Error attaching logger appender", e); } } - private void detachLogger(Appender logger) { + private static void detachLogger(final Appender logger) { try { ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); if (logger != null && root.isAttached(logger)) { root.detachAppender(logger); } - } catch (Throwable ex) { - Log.e("GBApplication", "Error detaching logger appender", ex); + } catch (final Throwable e) { + LOG.error("Error detaching logger appender", e); } } + @VisibleForTesting public FileAppender getFileLogger() { return fileLogger; } @NonNull - public static String formatBytes(@Nullable byte[] bytes) { + public static String formatBytes(@Nullable final byte[] bytes) { if (bytes == null) { return "(null)"; } else if (bytes.length == 0) { @@ -194,13 +230,7 @@ public abstract class Logging { return builder.toString(); } - public static void logBytes(Logger logger, byte[] value) { - if (value != null) { - logger.warn("DATA: " + GB.hexdump(value, 0, value.length)); - } - } - - public static FileAppender createFileAppender(final String logDirectory) { + private static FileAppender createFileAppender(final String logDirectory) { final LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); final PatternLayoutEncoder ple = new PatternLayoutEncoder(); @@ -209,8 +239,8 @@ public abstract class Logging { ple.setContext(lc); ple.start(); - final SizeAndTimeBasedRollingPolicy rollingPolicy = new SizeAndTimeBasedRollingPolicy(); - final RollingFileAppender fileAppender = new RollingFileAppender(); + final SizeAndTimeBasedRollingPolicy rollingPolicy = new SizeAndTimeBasedRollingPolicy<>(); + final RollingFileAppender fileAppender = new RollingFileAppender<>(); rollingPolicy.setContext(lc); rollingPolicy.setFileNamePattern(logDirectory + "/gadgetbridge-%d{yyyy-MM-dd}.%i.log.zip"); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java index e809252e08..b28f9dd1c1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/SettingsActivity.java @@ -39,11 +39,14 @@ import android.widget.LinearLayout; import android.widget.Spinner; import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.core.app.ActivityCompat; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import androidx.preference.ListPreference; import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; +import androidx.preference.SwitchPreference; +import androidx.preference.SwitchPreferenceCompat; import com.bytehamster.lib.preferencesearch.SearchPreferenceResult; import com.google.android.material.color.DynamicColors; @@ -60,6 +63,7 @@ import java.util.Set; import nodomain.freeyourgadget.gadgetbridge.BuildConfig; import nodomain.freeyourgadget.gadgetbridge.GBApplication; +import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.R; import nodomain.freeyourgadget.gadgetbridge.activities.automations.AutomationsSettingsActivity; import nodomain.freeyourgadget.gadgetbridge.activities.charts.ChartsPreferencesActivity; @@ -160,15 +164,15 @@ public class SettingsActivity extends AbstractSettingsActivityV2 { }); } - pref = findPreference("log_to_file"); - if (pref != null) { - pref.setOnPreferenceChangeListener((preference, newVal) -> { + final SwitchPreferenceCompat logToFilePreference = findPreference("log_to_file"); + if (logToFilePreference != null) { + logToFilePreference.setOnPreferenceChangeListener((preference, newVal) -> { boolean doEnable = Boolean.TRUE.equals(newVal); try { if (doEnable) { FileUtils.getExternalFilesDir(); // ensures that it is created } - GBApplication.setupLogging(doEnable); + Logging.getInstance().setFileLoggingEnabled(doEnable); } catch (IOException ex) { GB.toast(requireContext().getApplicationContext(), getString(R.string.error_creating_directory_for_logfiles, ex.getLocalizedMessage()), @@ -179,10 +183,24 @@ public class SettingsActivity extends AbstractSettingsActivityV2 { return true; }); - // If we didn't manage to initialize file logging, disable the preference - if (!GBApplication.getLogging().isFileLoggerInitialized()) { - pref.setEnabled(false); - pref.setSummary(R.string.pref_write_logfiles_not_available); + // If we didn't manage to initialize file logging, disable the preference and show the button to initialize again + if (!Logging.getInstance().isFileLoggerInitialized()) { + logToFilePreference.setEnabled(false); + logToFilePreference.setSummary(R.string.pref_write_logfiles_not_available); + final Preference logRestart = findPreference("log_restart"); + if (logRestart != null) { + logRestart.setVisible(true); + logRestart.setOnPreferenceClickListener(preference -> { + Logging.getInstance().setFileLoggingEnabled(logToFilePreference.isChecked()); + if (Logging.getInstance().isFileLoggerInitialized()) { + logToFilePreference.setEnabled(true); + logToFilePreference.setSummary(null); + logRestart.setVisible(false); + + } + return true; + }); + } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseDebugFragment.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseDebugFragment.kt index 21694c785e..e6726f1e31 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseDebugFragment.kt +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseDebugFragment.kt @@ -10,6 +10,8 @@ import nodomain.freeyourgadget.gadgetbridge.GBDatabaseManager import nodomain.freeyourgadget.gadgetbridge.R import nodomain.freeyourgadget.gadgetbridge.database.DBHelper import nodomain.freeyourgadget.gadgetbridge.util.GB +import org.slf4j.Logger +import org.slf4j.LoggerFactory class DatabaseDebugFragment : AbstractDebugFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { @@ -59,7 +61,7 @@ class DatabaseDebugFragment : AbstractDebugFragment() { tableNames.sortWith(Comparator { o1, o2 -> o1.compareTo(o2, true) }) } } catch (e: Exception) { - GB.log("Error accessing database", GB.ERROR, e) + LOG.error("Error accessing database", e) } for (tableName in tableNames) { @@ -142,11 +144,13 @@ class DatabaseDebugFragment : AbstractDebugFragment() { db.database.execSQL("DROP TABLE IF EXISTS TABLE_NAME_TO_DROP_HERE") } } catch (e: Exception) { - GB.log("Error accessing database", GB.ERROR, e) + LOG.error("Error accessing database", e) } } companion object { + private val LOG: Logger = LoggerFactory.getLogger(DatabaseDebugFragment::class.java) + private const val PREF_DEBUG_DATABASE_VERSION = "pref_debug_database_version" private const val DANGEROUS_ACTIONS = "dangerous_actions" private const val PREF_DEBUG_DELETE_OLD_DATABASE = "pref_debug_delete_old_database" diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseTableDebugFragment.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseTableDebugFragment.kt index 2a9a1fabd0..e7f7f0bd57 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseTableDebugFragment.kt +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/DatabaseTableDebugFragment.kt @@ -111,7 +111,7 @@ class DatabaseTableDebugFragment : AbstractDebugFragment() { } } } catch (e: Exception) { - GB.log("Error accessing database", GB.ERROR, e) + LOG.error("Error accessing database", e) } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/MainDebugFragment.kt b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/MainDebugFragment.kt index 3a3a8fc0e0..6da29446a2 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/MainDebugFragment.kt +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/activities/debug/MainDebugFragment.kt @@ -8,15 +8,15 @@ import androidx.core.content.FileProvider import androidx.preference.Preference import androidx.preference.SwitchPreferenceCompat import com.google.android.material.dialog.MaterialAlertDialogBuilder -import nodomain.freeyourgadget.gadgetbridge.GBApplication +import nodomain.freeyourgadget.gadgetbridge.Logging import nodomain.freeyourgadget.gadgetbridge.R import nodomain.freeyourgadget.gadgetbridge.activities.CameraActivity import nodomain.freeyourgadget.gadgetbridge.activities.PermissionsActivity import nodomain.freeyourgadget.gadgetbridge.activities.welcome.WelcomeActivity import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEventCameraRemote +import nodomain.freeyourgadget.gadgetbridge.util.DeviceTypeDialog import nodomain.freeyourgadget.gadgetbridge.util.FileUtils import nodomain.freeyourgadget.gadgetbridge.util.GB -import nodomain.freeyourgadget.gadgetbridge.util.DeviceTypeDialog import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File @@ -24,8 +24,11 @@ import java.io.IOException import java.lang.Boolean import kotlin.Any import kotlin.String +import kotlin.Suppress +import kotlin.apply import kotlin.let +@Suppress("unused") class MainDebugFragment : AbstractDebugFragment() { override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) { setPreferencesFromResource(R.xml.debug_preferences_main, rootKey) @@ -37,14 +40,15 @@ class MainDebugFragment : AbstractDebugFragment() { } onClick(PREF_DEBUG_SHARE_LOGS) { showLogSharingWarning() } - findPreference(LOG_TO_FILE)?.let { + val logToFilePreference = findPreference(LOG_TO_FILE) + logToFilePreference?.let { it.setOnPreferenceChangeListener { _: Preference?, newVal: Any? -> val doEnable = Boolean.TRUE == newVal try { if (doEnable) { FileUtils.getExternalFilesDir() // ensures that it is created } - GBApplication.setupLogging(doEnable) + Logging.getInstance().setFileLoggingEnabled(doEnable) } catch (ex: IOException) { GB.toast( requireContext().applicationContext, @@ -58,10 +62,29 @@ class MainDebugFragment : AbstractDebugFragment() { } // If we didn't manage to initialize file logging, disable the preference - if (!GBApplication.getLogging().isFileLoggerInitialized) { + if (!Logging.getInstance().isFileLoggerInitialized) { it.isEnabled = false it.setSummary(R.string.pref_write_logfiles_not_available) } + + // If we didn't manage to initialize file logging, disable the preference and show the button to initialize again + if (!Logging.getInstance().isFileLoggerInitialized()) { + logToFilePreference.isEnabled = false + logToFilePreference.setSummary(R.string.pref_write_logfiles_not_available) + val logRestart = findPreference("log_restart") + if (logRestart != null) { + logRestart.isVisible = true + logRestart.setOnPreferenceClickListener { preference: Preference? -> + Logging.getInstance().setFileLoggingEnabled(logToFilePreference.isChecked) + if (Logging.getInstance().isFileLoggerInitialized) { + logToFilePreference.isEnabled = true + logToFilePreference.setSummary(null) + logRestart.isVisible = false + } + true + } + } + } } if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O) { @@ -99,15 +122,13 @@ class MainDebugFragment : AbstractDebugFragment() { } private fun shareLog() { - val fileName = GBApplication.getLogPath() + val fileName = Logging.getInstance().logPath if (fileName == null || fileName.isEmpty()) { return } // Flush the logs, so that we ensure latest lines are also there - GBApplication.getLogging().setImmediateFlush(true) - LOG.debug("Flushing logs before sharing") - GBApplication.getLogging().setImmediateFlush(false) + Logging.getInstance().flush() val logFile = File(fileName) if (!logFile.exists()) { @@ -135,6 +156,7 @@ class MainDebugFragment : AbstractDebugFragment() { private const val PREF_DEBUG_ADD_TEST_DEVICE = "pref_debug_add_test_device" private const val PREF_HEADER_LOGS = "pref_header_logs" private const val LOG_TO_FILE = "log_to_file" + private const val LOG_RESTART = "log_restart" private const val PREF_DEBUG_SHARE_LOGS = "pref_debug_share_logs" private const val PREF_HEADER_DEBUG = "pref_header_debug" private const val PREF_DEBUG_NOTIFICATIONS = "pref_debug_notifications" diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java index cf1f8ed672..6f07b5cd7b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/deviceevents/GBDeviceEventDisplayMessage.java @@ -21,10 +21,15 @@ import android.content.Intent; import androidx.localbroadcastmanager.content.LocalBroadcastManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.util.GB; public class GBDeviceEventDisplayMessage extends GBDeviceEvent { + private static final Logger LOG = LoggerFactory.getLogger(GBDeviceEventDisplayMessage.class); + public String message; public int duration; public int severity; @@ -33,10 +38,6 @@ public class GBDeviceEventDisplayMessage extends GBDeviceEvent { * An event for displaying a message to the user. How the message is displayed * is a detail of the current activity, which needs to listen to the Intent * GB.ACTION_DISPLAY_MESSAGE. - * - * @param message - * @param duration - * @param severity */ public GBDeviceEventDisplayMessage(String message, int duration, int severity) { this.message = message; @@ -46,7 +47,7 @@ public class GBDeviceEventDisplayMessage extends GBDeviceEvent { @Override public void evaluate(final Context context, final GBDevice device) { - GB.log(this.message, this.severity, null); + GB.log(LOG, this.message, this.severity, null); Intent messageIntent = new Intent(GB.ACTION_DISPLAY_MESSAGE); messageIntent.putExtra(GB.DISPLAY_MESSAGE_MESSAGE, this.message); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ImageEditActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ImageEditActivity.java index a484275ede..4931d30fe1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ImageEditActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/ImageEditActivity.java @@ -28,13 +28,15 @@ import android.graphics.PorterDuff; import android.net.Uri; import android.os.Bundle; import android.provider.MediaStore; -import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.IOException; import nodomain.freeyourgadget.gadgetbridge.R; @@ -44,6 +46,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fos import nodomain.freeyourgadget.gadgetbridge.util.GB; public class ImageEditActivity extends AbstractGBActivity implements View.OnTouchListener { + private static final Logger LOG = LoggerFactory.getLogger(ImageEditActivity.class); + static final public int RESULT_CODE_EDIT_SUCCESS = 0; ImageView overlay; @@ -85,7 +89,7 @@ public class ImageEditActivity extends AbstractGBActivity implements View.OnTouc try { fitImageToLayout(mainLayout); } catch (IOException | RuntimeException e) { - GB.log("Error formatting image", GB.ERROR, e); + LOG.error("Error formatting image", e); GB.toast("Error formatting image", Toast.LENGTH_LONG, GB.ERROR); finish(); } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java index 8181902ac1..801bda1732 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/NotificationConfiguration.java @@ -16,8 +16,6 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.devices.qhybrid; -import android.util.Log; - import java.io.Serializable; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; @@ -29,15 +27,6 @@ public class NotificationConfiguration implements Serializable { private boolean respectSilentMode; private long id = -1; - NotificationConfiguration(short min, short hour, String packageName, String appName, boolean respectSilentMode, PlayNotificationRequest.VibrationType vibration) { - this.min = min; - this.hour = hour; - this.packageName = packageName; - this.appName = appName; - this.respectSilentMode = respectSilentMode; - this.vibration = vibration; - } - public NotificationConfiguration(short min, short hour, short subEye, PlayNotificationRequest.VibrationType vibration) { this.min = min; this.hour = hour; @@ -81,7 +70,6 @@ public class NotificationConfiguration implements Serializable { } public boolean getRespectSilentMode() { - Log.d("Config", "respect: " + respectSilentMode); return respectSilentMode; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java index aee688f240..f6916bec34 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/PackageConfigHelper.java @@ -20,16 +20,19 @@ import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.ArrayList; import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit.PlayNotificationRequest; -import nodomain.freeyourgadget.gadgetbridge.util.GB; public class PackageConfigHelper { + private static final Logger LOG = LoggerFactory.getLogger(PackageConfigHelper.class); + public static final String DB_NAME = "qhybridNotifications.db"; public static final String DB_ID = "id"; public static final String DB_TABLE = "notifications"; @@ -45,7 +48,7 @@ public class PackageConfigHelper { try { initDB(); } catch (Exception e) { - GB.log("error getting database", GB.ERROR, e); + LOG.error("error getting database", e); } } @@ -96,7 +99,7 @@ public class PackageConfigHelper { PlayNotificationRequest.VibrationType.fromValue((byte) cursor.getInt(vibrationPos)), cursor.getInt(idPos) )); - Log.d("Settings", "setting #" + cursor.getPosition() + ": " + cursor.getInt(silentPos)); + LOG.debug("setting #{}: {}", cursor.getPosition(), cursor.getInt(silentPos)); } while (cursor.moveToNext()); } return list; @@ -115,16 +118,15 @@ public class PackageConfigHelper { return null; } c.moveToFirst(); - NotificationConfiguration settings = new NotificationConfiguration( - (short) c.getInt(c.getColumnIndex(DB_MINUTE)), - (short) c.getInt(c.getColumnIndex(DB_HOUR)), - c.getString(c.getColumnIndex(DB_PACKAGE)), - c.getString(c.getColumnIndex(DB_APPNAME)), - c.getInt(c.getColumnIndex(DB_RESPECT_SILENT)) == 1, - PlayNotificationRequest.VibrationType.fromValue((byte) c.getInt(c.getColumnIndex(DB_VIBRATION))), - c.getInt(c.getColumnIndex(DB_ID)) + return new NotificationConfiguration( + (short) c.getInt(c.getColumnIndexOrThrow(DB_MINUTE)), + (short) c.getInt(c.getColumnIndexOrThrow(DB_HOUR)), + c.getString(c.getColumnIndexOrThrow(DB_PACKAGE)), + c.getString(c.getColumnIndexOrThrow(DB_APPNAME)), + c.getInt(c.getColumnIndexOrThrow(DB_RESPECT_SILENT)) == 1, + PlayNotificationRequest.VibrationType.fromValue((byte) c.getInt(c.getColumnIndexOrThrow(DB_VIBRATION))), + c.getInt(c.getColumnIndexOrThrow(DB_ID)) ); - return settings; } } } @@ -145,7 +147,7 @@ public class PackageConfigHelper { } public void deleteNotificationConfiguration(NotificationConfiguration packageSettings) throws Exception { - Log.d("DB", "deleting id " + packageSettings.getId()); + LOG.debug("deleting id {}", packageSettings.getId()); if(packageSettings.getId() == -1) return; try (DBHandler db = GBApplication.acquireDB()) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridConfigActivity.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridConfigActivity.java index 0c3964f595..20df3d3052 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridConfigActivity.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/devices/qhybrid/QHybridConfigActivity.java @@ -24,11 +24,10 @@ import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; -import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.Gravity; import android.view.KeyEvent; @@ -64,6 +63,8 @@ import com.google.android.material.dialog.MaterialAlertDialogBuilder; import org.json.JSONArray; import org.json.JSONException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.text.DecimalFormat; import java.util.ArrayList; @@ -80,8 +81,11 @@ import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.QHybridSuppo import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.adapter.fossil.FossilWatchAdapter; import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.buttonconfig.ConfigPayload; import nodomain.freeyourgadget.gadgetbridge.util.GB; +import nodomain.freeyourgadget.gadgetbridge.util.NotificationUtils; public class QHybridConfigActivity extends AbstractGBActivity { + private static final Logger LOG = LoggerFactory.getLogger(QHybridConfigActivity.class); + PackageAdapter adapter; ArrayList list; PackageConfigHelper helper; @@ -469,7 +473,7 @@ public class QHybridConfigActivity extends AbstractGBActivity { buttonIntent.putExtra(FossilWatchAdapter.ITEM_BUTTONS, buttonConfig.toString()); LocalBroadcastManager.getInstance(QHybridConfigActivity.this).sendBroadcast(buttonIntent); } catch (JSONException e) { - GB.log("error", GB.ERROR, e); + LOG.error("Failed to update button config", e); } } }) @@ -572,11 +576,8 @@ public class QHybridConfigActivity extends AbstractGBActivity { } class PackageAdapter extends ArrayAdapter { - PackageManager manager; - PackageAdapter(@NonNull Context context, int resource, @NonNull List objects) { super(context, resource, objects); - manager = context.getPackageManager(); } @NonNull @@ -599,10 +600,9 @@ public class QHybridConfigActivity extends AbstractGBActivity { return addButton; } - try { - ((ImageView) view.findViewById(R.id.packageIcon)).setImageDrawable(manager.getApplicationIcon(settings.getPackageName())); - } catch (PackageManager.NameNotFoundException e) { - GB.log("error", GB.ERROR, e); + final Drawable appIcon = NotificationUtils.getAppIcon(getContext(), settings.getPackageName()); + if (appIcon != null) { + ((ImageView) view.findViewById(R.id.packageIcon)).setImageDrawable(appIcon); } final int square_side = 100; ((TextView) view.findViewById(R.id.packageName)).setText(settings.getAppName()); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/GBPrefsMigrator.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/GBPrefsMigrator.java index 7c95c42ebf..79e637aa24 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/GBPrefsMigrator.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/GBPrefsMigrator.java @@ -1,12 +1,14 @@ package nodomain.freeyourgadget.gadgetbridge.prefs; import android.content.SharedPreferences; -import android.util.Log; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import nodomain.freeyourgadget.gadgetbridge.prefs.migrators.PreferenceMigrator55; public class GBPrefsMigrator { - private static final String TAG = "GBPrefsMigrator"; + private static final Logger LOG = LoggerFactory.getLogger(GBPrefsMigrator.class); public static final String PREFS_VERSION = "shared_preferences_version"; //if preferences have to be migrated, increment the following and add the migration logic in migratePrefs below @@ -16,7 +18,7 @@ public class GBPrefsMigrator { public static void migratePrefsIfNeeded(final SharedPreferences sharedPrefs) { final int oldVersion = getPrefsFileVersion(sharedPrefs); if (oldVersion != CURRENT_PREFS_VERSION) { - Log.i(TAG, "Migrating preferences from " + oldVersion + " to " + CURRENT_PREFS_VERSION); + LOG.info("Migrating preferences from {} to {}", oldVersion, CURRENT_PREFS_VERSION); final SharedPreferences.Editor editor = sharedPrefs.edit(); diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/migrators/PreferenceMigrator55.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/migrators/PreferenceMigrator55.java index fb93cc1c2e..4cdba222f1 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/migrators/PreferenceMigrator55.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/prefs/migrators/PreferenceMigrator55.java @@ -16,10 +16,11 @@ import static nodomain.freeyourgadget.gadgetbridge.model.DeviceType.WATCHXPLUS; import android.content.SharedPreferences; import android.os.Build; -import android.util.Log; import org.apache.commons.lang3.StringUtils; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.io.InputStream; import java.util.ArrayList; @@ -52,6 +53,8 @@ import nodomain.freeyourgadget.gadgetbridge.util.Prefs; */ @SuppressWarnings("deprecation") public class PreferenceMigrator55 extends AbstractPreferenceMigrator { + private static final Logger LOG = LoggerFactory.getLogger(PreferenceMigrator55.class); + private final SharedPreferences sharedPrefs; private final GBPrefs prefs; @@ -97,7 +100,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { try { legacyGender_1 = sharedPrefs.getInt(ActivityUser.PREF_USER_GENDER, 2); } catch (Exception e) { - Log.e(TAG, "Could not access legacy activity gender", e); + LOG.error("Could not access legacy activity gender", e); } editor.putString(ActivityUser.PREF_USER_GENDER, Integer.toString(legacyGender_1)); } @@ -213,7 +216,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.remove("miband3_language"); } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 3", e); + LOG.error("Failed to migrate prefs to version 3", e); } } if (oldVersion < 4) { @@ -233,7 +236,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 4", e); + LOG.error("Failed to migrate prefs to version 4", e); } } if (oldVersion < 5) { @@ -297,7 +300,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.remove("zetime_wrist"); } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 5", e); + LOG.error("Failed to migrate prefs to version 5", e); } } if (oldVersion < 6) { @@ -331,9 +334,9 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { DaoSession daoSession = db.getDaoSession(); List activeDevices = DBHelper.getActiveDevices(daoSession); migrateBooleanPrefToPerDevicePref("transliteration", false, "pref_transliteration_enabled", (ArrayList) activeDevices); - Log.w(TAG, "migrating transliteration settings"); + LOG.warn("migrating transliteration settings"); } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 9", e); + LOG.error("Failed to migrate prefs to version 9", e); } } if (oldVersion < 10) { @@ -347,14 +350,14 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName()); if (deviceType == GALAXY_BUDS) { - GB.log("migrating Galaxy Buds volume", GB.INFO, null); + LOG.info("migrating Galaxy Buds volume"); String volume = deviceSharedPrefs.getString(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME, "1"); deviceSharedPrefsEdit.putInt(DeviceSettingsPreferenceConst.PREF_GALAXY_BUDS_AMBIENT_VOLUME, Integer.parseInt(volume)); } deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 10", e); + LOG.error("Failed to migrate prefs to version 10", e); } } if (oldVersion < 11) { @@ -445,7 +448,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.remove("mi2_inactivity_warnings_end"); editor.remove("mi_fitness_goal"); } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 11", e); + LOG.error("Failed to migrate prefs to version 11", e); } } if (oldVersion < 12) { @@ -485,7 +488,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 13", e); + LOG.error("Failed to migrate prefs to version 13", e); } } @@ -509,7 +512,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 14", e); + LOG.error("Failed to migrate prefs to version 14", e); } } @@ -528,7 +531,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 15", e); + LOG.error("Failed to migrate prefs to version 15", e); } } @@ -552,7 +555,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 16", e); + LOG.error("Failed to migrate prefs to version 16", e); } } @@ -576,7 +579,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 17", e); + LOG.error("Failed to migrate prefs to version 17", e); } editor.remove(GBPrefs.CALENDAR_BLACKLIST); @@ -602,7 +605,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 18", e); + LOG.error("Failed to migrate prefs to version 18", e); } } @@ -637,7 +640,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 20", e); + LOG.error("Failed to migrate prefs to version 20", e); } } @@ -667,7 +670,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 21", e); + LOG.error("Failed to migrate prefs to version 21", e); } } @@ -687,7 +690,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 22", e); + LOG.error("Failed to migrate prefs to version 22", e); } } @@ -716,7 +719,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 26", e); + LOG.error("Failed to migrate prefs to version 26", e); } } @@ -747,7 +750,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 27", e); + LOG.error("Failed to migrate prefs to version 27", e); } } @@ -788,7 +791,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 28", e); + LOG.error("Failed to migrate prefs to version 28", e); } } @@ -810,7 +813,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 29", e); + LOG.error("Failed to migrate prefs to version 29", e); } } @@ -832,7 +835,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 30", e); + LOG.error("Failed to migrate prefs to version 30", e); } } @@ -862,7 +865,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 31", e); + LOG.error("Failed to migrate prefs to version 31", e); } } @@ -892,7 +895,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 32", e); + LOG.error("Failed to migrate prefs to version 32", e); } } @@ -922,7 +925,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 33", e); + LOG.error("Failed to migrate prefs to version 33", e); } } @@ -963,7 +966,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 34", e); + LOG.error("Failed to migrate prefs to version 34", e); } } @@ -1029,7 +1032,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 35", e); + LOG.error("Failed to migrate prefs to version 35", e); } } if (oldVersion < 36) { @@ -1065,7 +1068,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 36", e); + LOG.error("Failed to migrate prefs to version 36", e); } } @@ -1086,11 +1089,11 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { if (yearOfBirthValue > 1800 && yearOfBirthValue < 3000) { editor.putString("activity_user_date_of_birth", String.format(Locale.ROOT, "%s-01-01", yearOfBirth.trim())); } else { - Log.e(TAG, "Year of birth out of range, not migrating - " + yearOfBirth); + LOG.error("Year of birth out of range, not migrating - " + yearOfBirth); } } } catch (final Exception e) { - Log.e(TAG, "Failed to migrate year of birth to date of birth in version 38", e); + LOG.error("Failed to migrate year of birth to date of birth in version 38", e); } } @@ -1122,7 +1125,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 39", e); + LOG.error("Failed to migrate prefs to version 39", e); } } @@ -1152,7 +1155,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 40", e); + LOG.error("Failed to migrate prefs to version 40", e); } } @@ -1201,7 +1204,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 43", e); + LOG.error("Failed to migrate prefs to version 43", e); } } @@ -1215,7 +1218,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.putBoolean("first_run", false); } } catch (final Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 44", e); + LOG.error("Failed to migrate prefs to version 44", e); } } @@ -1249,7 +1252,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 45", e); + LOG.error("Failed to migrate prefs to version 45", e); } } @@ -1268,7 +1271,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 46", e); + LOG.error("Failed to migrate prefs to version 46", e); } } @@ -1315,7 +1318,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 49", e); + LOG.error("Failed to migrate prefs to version 49", e); } } @@ -1349,7 +1352,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 50", e); + LOG.error("Failed to migrate prefs to version 50", e); } } @@ -1384,7 +1387,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { deviceSharedPrefsEdit.apply(); } } catch (Exception e) { - Log.e(TAG, "Failed to migrate prefs to version 54", e); + LOG.error("Failed to migrate prefs to version 54", e); } } } @@ -1419,7 +1422,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { } } } catch (Exception e) { - Log.e(TAG, "Failed to migrate device types", e); + LOG.error("Failed to migrate device types", e); } } @@ -1436,7 +1439,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName()); if (deviceTypes.contains(deviceType)) { - Log.i(TAG, "migrating global string preference " + globalPref + " for " + deviceType.name() + " " + dbDevice.getIdentifier()); + LOG.info("migrating global string preference {} for {} {}", globalPref, deviceType.name(), dbDevice.getIdentifier()); deviceSharedPrefsEdit.putString(perDevicePref, globalPrefValue); } deviceSharedPrefsEdit.apply(); @@ -1445,7 +1448,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.remove(globalPref); editor.apply(); } catch (Exception e) { - Log.w(TAG, "error acquiring DB lock"); + LOG.warn("error acquiring DB lock"); } } @@ -1463,7 +1466,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { DeviceType deviceType = DeviceType.fromName(dbDevice.getTypeName()); if (deviceTypes.contains(deviceType)) { - Log.i(TAG, "migrating global boolean preference " + globalPref + " for " + deviceType.name() + " " + dbDevice.getIdentifier()); + LOG.info("migrating global boolean preference {} for {} {}", globalPref, deviceType.name(), dbDevice.getIdentifier()); deviceSharedPrefsEdit.putBoolean(perDevicePref, globalPrefValue); } deviceSharedPrefsEdit.apply(); @@ -1472,7 +1475,7 @@ public class PreferenceMigrator55 extends AbstractPreferenceMigrator { editor.remove(globalPref); editor.apply(); } catch (Exception e) { - Log.e(TAG, "Failed to migrate " + globalPref, e); + LOG.error("Failed to migrate {}", globalPref, e); } } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btbr/AbstractBTBRDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btbr/AbstractBTBRDeviceSupport.java index 9a2c07bbc1..e7fc0bccab 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btbr/AbstractBTBRDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btbr/AbstractBTBRDeviceSupport.java @@ -24,7 +24,6 @@ import org.slf4j.Logger; import java.util.UUID; -import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport; import nodomain.freeyourgadget.gadgetbridge.service.btle.BleNamesResolver; @@ -173,14 +172,6 @@ public abstract class AbstractBTBRDeviceSupport extends AbstractDeviceSupport im return 0; } - /** - * Utility method that may be used to log incoming messages when we don't know how to deal with them yet. - */ - public void logMessageContent(byte[] value) { - logger.info("RECEIVED DATA WITH LENGTH: {}", (value != null) ? value.length : "(null)"); - Logging.logBytes(logger, value); - } - @Override public void onConnectionEstablished() { try { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEMultiDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEMultiDeviceSupport.java index 4cb4b77176..d493b716f6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEMultiDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLEMultiDeviceSupport.java @@ -44,7 +44,6 @@ import java.util.Set; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.CheckInitializedAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile; @@ -81,7 +80,9 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractBTLEDeviceS public AbstractBTLEMultiDeviceSupport(Logger logger, int deviceCount) { this.logger = logger; this.deviceCount = deviceCount; + //noinspection unchecked mSupportedServices = new Set[deviceCount]; + //noinspection unchecked mSupportedServerServices = new Set[deviceCount]; mMTUs = new int[deviceCount]; for (int i = 0; i < deviceCount; i++) { @@ -92,16 +93,13 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractBTLEDeviceS mQueues = new BtLEQueue[deviceCount]; bleApis = new BleIntentApi[deviceCount]; devices = new GBDevice[deviceCount]; + //noinspection unchecked mAvailableCharacteristics = new Map[deviceCount]; if (logger == null) { throw new IllegalArgumentException("logger must not be null"); } } - public AbstractBTLEMultiDeviceSupport(Logger logger) { - this(logger, 1); - } - private void validateDeviceIndex(int deviceIdx) { if (deviceIdx < 0 || deviceIdx > deviceCount) { throw new IllegalArgumentException( @@ -429,14 +427,6 @@ public abstract class AbstractBTLEMultiDeviceSupport extends AbstractBTLEDeviceS return mSupportedServices[deviceIdx]; } - /** - * Utility method that may be used to log incoming messages when we don't know how to deal with them yet. - */ - public void logMessageContent(byte[] value) { - logger.info("RECEIVED DATA WITH LENGTH: {}", (value != null) ? value.length : "(null)"); - Logging.logBytes(logger, value); - } - // default implementations of event handler methods (gatt callbacks) @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLESingleDeviceSupport.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLESingleDeviceSupport.java index 36197377e5..fc8ba6daf0 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLESingleDeviceSupport.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/btle/AbstractBTLESingleDeviceSupport.java @@ -44,10 +44,10 @@ import java.util.Set; import java.util.UUID; import nodomain.freeyourgadget.gadgetbridge.GBApplication; -import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.service.btle.actions.CheckInitializedAction; import nodomain.freeyourgadget.gadgetbridge.service.btle.profiles.AbstractBleProfile; +import nodomain.freeyourgadget.gadgetbridge.util.GB; import nodomain.freeyourgadget.gadgetbridge.util.Prefs; /** @@ -111,10 +111,6 @@ public abstract class AbstractBTLESingleDeviceSupport extends AbstractBTLEDevice } } - public BleIntentApi getBleApi() { - return bleApi; - } - @Override public void onSendConfiguration(String config) { super.onSendConfiguration(config); @@ -339,8 +335,11 @@ public abstract class AbstractBTLESingleDeviceSupport extends AbstractBTLEDevice * Utility method that may be used to log incoming messages when we don't know how to deal with them yet. */ public void logMessageContent(byte[] value) { - logger.info("RECEIVED DATA WITH LENGTH: {}", (value != null) ? value.length : "(null)"); - Logging.logBytes(logger, value); + if (value != null) { + logger.info("RECEIVED DATA WITH LENGTH: {}: {}", value.length, GB.hexdump(value)); + } else { + logger.warn("RECEIVED DATA: (null)"); + } } // default implementations of event handler methods (gatt callbacks) diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/parser/ActivityFileParser.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/parser/ActivityFileParser.java index edfd7d4a76..124f9ddaa6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/parser/ActivityFileParser.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/parser/ActivityFileParser.java @@ -16,21 +16,16 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.parser; -import android.util.Log; - import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.ArrayList; -import java.util.Map; import nodomain.freeyourgadget.gadgetbridge.entities.BaseActivitySummary; import nodomain.freeyourgadget.gadgetbridge.entities.HybridHRSpo2Sample; import nodomain.freeyourgadget.gadgetbridge.model.ActivityKind; -import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; -import nodomain.freeyourgadget.gadgetbridge.util.StringUtils; public class ActivityFileParser { diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java index 94b8108a73..9de409ad53 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/Request.java @@ -17,7 +17,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests; import android.bluetooth.BluetoothGattCharacteristic; -import android.util.Log; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -28,7 +27,7 @@ import java.util.UUID; public abstract class Request { protected byte[] data; - private Logger logger = (Logger) LoggerFactory.getLogger(getName()); + private final Logger logger = LoggerFactory.getLogger(getName()); //protected ByteBuffer buffer; public Request(){ diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceSecurityVersionInfo.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceSecurityVersionInfo.java index 3f5aa71657..31020b9b4b 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceSecurityVersionInfo.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil/device_info/DeviceSecurityVersionInfo.java @@ -16,16 +16,8 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil.device_info; -import android.util.Log; - import androidx.annotation.NonNull; -import java.nio.ByteBuffer; -import java.nio.ByteOrder; -import java.util.HashMap; - -import nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.file.FileHandle; - public class DeviceSecurityVersionInfo implements DeviceInfo { private int versionMajor, versionMinor; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java index 01e0101a03..b528b7b4ea 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/fossil_hr/file/ResultCode.java @@ -16,8 +16,6 @@ along with this program. If not, see . */ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.fossil_hr.file; -import nodomain.freeyourgadget.gadgetbridge.util.GB; - public enum ResultCode { SUCCESS(0, true), INVALID_OPERATION_DATA(1, false), @@ -46,24 +44,21 @@ public enum ResultCode { // no clue what there one mean UNKNOWN_1(-125, false); - boolean success; - int code; + final boolean success; + final int code; - private ResultCode(int code, boolean success){ + ResultCode(int code, boolean success) { this.code = code; this.success = success; } - public boolean inidicatesSuccess(){ + public boolean inidicatesSuccess() { return this.success; } - public static ResultCode fromCode(int code){ - for (ResultCode resultCode : ResultCode.values()){ - if(resultCode.code == code) { - if(resultCode == UNKNOWN_1){ - GB.log("dunno what code this is: " + code, GB.INFO, null); - } + public static ResultCode fromCode(int code) { + for (ResultCode resultCode : ResultCode.values()) { + if (resultCode.code == code) { return resultCode; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java index c7c7622b29..35bc477ce6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/EraseFileRequest.java @@ -17,7 +17,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit; import android.bluetooth.BluetoothGattCharacteristic; -import android.util.Log; import java.nio.ByteBuffer; import java.nio.ByteOrder; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java index abf8a5791d..5a62883ed5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/service/devices/qhybrid/requests/misfit/GetCountdownSettingsRequest.java @@ -17,7 +17,6 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.qhybrid.requests.misfit; import android.bluetooth.BluetoothGattCharacteristic; -import android.util.Log; import java.nio.ByteBuffer; diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java index a8c1c18773..190cd0e488 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/AlarmUtils.java @@ -20,6 +20,9 @@ package nodomain.freeyourgadget.gadgetbridge.util; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; @@ -43,6 +46,8 @@ import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; * Some utility methods for dealing with Alarms. */ public class AlarmUtils { + private static final Logger LOG = LoggerFactory.getLogger(AlarmUtils.class); + /** * Creates an auto-generated (not user-configurable), non-recurring alarm. This alarm * may not be stored in the database. Some features are not available (e.g. device id, user id). @@ -58,8 +63,6 @@ public class AlarmUtils { /** * Creates a default Alarm - * @param device - * @param position */ @Nullable public static Alarm createDefaultAlarm(GBDevice gbDevice, int position) { @@ -67,7 +70,7 @@ public class AlarmUtils { DaoSession daoSession = db.getDaoSession(); return createDefaultAlarm(daoSession, gbDevice, position); } catch (Exception e) { - GB.log("Error accessing database", GB.ERROR, e); + LOG.error("Error accessing database", e); return null; } } @@ -146,7 +149,7 @@ public class AlarmUtils { Collections.sort(alarms, AlarmUtils.createComparator()); return alarms; } catch (Exception e) { - GB.log("Error accessing database", GB.ERROR, e); + LOG.error("Error accessing database", e); return Collections.emptyList(); } } @@ -188,7 +191,7 @@ public class AlarmUtils { daoSession.insertOrReplace(oneshot); all_alarms = DBHelper.getAlarms(gbDevice); } catch (Exception e) { - GB.log("error storing one shot quick alarm", GB.ERROR, e); + LOG.error("error storing one shot quick alarm", e); } return all_alarms; } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java index b9931272ca..e9e1bcc3b5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/FileUtils.java @@ -26,6 +26,9 @@ import android.os.Environment; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.BufferedReader; @@ -52,8 +55,7 @@ import nodomain.freeyourgadget.gadgetbridge.GBApplication; import nodomain.freeyourgadget.gadgetbridge.GBEnvironment; public class FileUtils { - // Don't use slf4j here -- would be a bootstrapping problem - private static final String TAG = "FileUtils"; + private static final Logger LOG = LoggerFactory.getLogger(FileUtils.class); private static final List KNOWN_PACKAGES = Arrays.asList( "nodomain.freeyourgadget.gadgetbridge", @@ -65,10 +67,6 @@ public class FileUtils { /** * Copies the the given sourceFile to destFile, overwriting it, in case it exists. - * - * @param sourceFile - * @param destFile - * @throws IOException */ public static void copyFile(File sourceFile, File destFile) throws IOException { if (!sourceFile.exists()) { @@ -89,7 +87,6 @@ public class FileUtils { * Copies the contents of the given input stream to the destination file. * @param inputStream the contents to write. Note: the caller has to close the input stream! * @param destFile the file to write to - * @throws IOException */ public static void copyStreamToFile(InputStream inputStream, File destFile) throws IOException { try (FileOutputStream fout = new FileOutputStream(destFile)) { @@ -105,7 +102,6 @@ public class FileUtils { * Copies the contents of the given string to the destination file. * @param string the contents to write. * @param dst the file to write to - * @throws IOException */ public static void copyStringToFile(String string, File dst, String mode) throws IOException { boolean append = true; @@ -120,7 +116,6 @@ public class FileUtils { * Copies the contents of the given file to the destination output stream. * @param src the file from which to read. * @param dst the output stream that is written to. Note: the caller has to close the output stream! - * @throws IOException */ public static void copyFileToStream(File src, OutputStream dst) throws IOException { try (FileInputStream in = new FileInputStream(src)) { @@ -153,7 +148,6 @@ public class FileUtils { * @param context the application context. * @param src the file from which the content should be copied. * @param dst the destination uri. - * @throws IOException */ public static void copyFileToURI(Context context, File src, Uri dst) throws IOException { OutputStream out = context.getContentResolver().openOutputStream(dst); @@ -170,7 +164,6 @@ public class FileUtils { * in UTF-8 encoding. * @param file the file to read * @return the file contents as a newline-delimited string - * @throws IOException * @see #getStringFromFile(File, String) */ public static String getStringFromFile(File file) throws IOException { @@ -182,7 +175,6 @@ public class FileUtils { * given encoding. * @param file the file to read * @return the file contents as a newline-delimited string - * @throws IOException * @see #getStringFromFile(File) */ public static String getStringFromFile(File file, String encoding) throws IOException { @@ -220,7 +212,6 @@ public class FileUtils { * It doesn't matter whether child shall represent a file or a directory. * The parent directory will automatically be created, if necessary. * @param child the path to become relative to the external files directory - * @throws IOException * @see #getExternalFilesDir() */ public static File getExternalFile(String child) throws IOException { @@ -245,7 +236,7 @@ public class FileUtils { file.delete(); return true; } catch (FileNotFoundException e) { - GB.log("Cannot write to directory: " + dir.getAbsolutePath(), GB.INFO, e); + LOG.debug("Cannot write to directory: {}", dir.getAbsolutePath(), e); return false; } } @@ -259,7 +250,6 @@ public class FileUtils { * can actually write to them. But when created, they *should* be writable. * * @return the list of writable directories - * @throws IOException */ @NonNull private static List getWritableExternalFilesDirs() throws IOException { @@ -284,20 +274,19 @@ public class FileUtils { if (dirs.length == 0) { throw new IOException("Unable to access external files dirs: 0"); } - for (int i = 0; i < dirs.length; i++) { - File dir = dirs[i]; + for (File dir : dirs) { if (dir == null) { continue; } if (!dir.exists() && !dir.mkdirs()) { - GB.log("Unable to create directories: " + dir.getAbsolutePath(), GB.INFO, null); + LOG.info("Unable to create directories: {}", dir.getAbsolutePath()); continue; } if (!GBEnvironment.env().isLocalTest()) { // don't do this with robolectric final String storageState = Environment.getExternalStorageState(dir); if (!Environment.MEDIA_MOUNTED.equals(storageState)) { - GB.log("ignoring '" + storageState + "' external storage dir: " + dir, GB.INFO, null); + LOG.info("ignoring '{}' external storage dir: {}", storageState, dir); continue; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java index ee23173291..3f28c310b5 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GB.java @@ -538,18 +538,22 @@ public class GB { } public static void log(String message, int severity, Throwable ex) { + log(LOG, message, severity, ex); + } + + public static void log(Logger logger, String message, int severity, Throwable ex) { switch (severity) { case INFO: - LOG.info(message, ex); + logger.info(message, ex); break; case WARN: - LOG.warn(message, ex); + logger.warn(message, ex); break; case ERROR: - LOG.error(message, ex); + logger.error(message, ex); break; case DEBUG: - LOG.debug(message, ex); + logger.debug(message, ex); } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java index 7b53ab6766..7cf6192e63 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/GBPrefs.java @@ -25,11 +25,13 @@ import android.content.pm.PackageManager; import android.location.Criteria; import android.location.Location; import android.location.LocationManager; -import android.util.Log; import androidx.annotation.Nullable; import androidx.core.app.ActivityCompat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + import java.text.ParseException; import java.time.LocalTime; import java.util.Date; @@ -39,8 +41,7 @@ import nodomain.freeyourgadget.gadgetbridge.activities.SettingsActivity; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; public class GBPrefs extends Prefs { - // Since this class must not log to slf4j, we use plain android.util.Log - private static final String TAG = "GBPrefs"; + private static final Logger LOG = LoggerFactory.getLogger(GBPrefs.class); public static final String PACKAGE_BLACKLIST = "package_blacklist"; public static final String PACKAGE_PEBBLEMSG_BLACKLIST = "package_pebblemsg_blacklist"; @@ -146,7 +147,7 @@ public class GBPrefs extends Prefs { try { return DateTimeUtils.dayFromString(date); } catch (ParseException ex) { - GB.log("Error parsing date: " + date, GB.ERROR, ex); + LOG.error("Error parsing date: {}", date, ex); return null; } } @@ -158,7 +159,7 @@ public class GBPrefs extends Prefs { public float[] getLongLat(Context context) { float latitude = getFloat("location_latitude", 0); float longitude = getFloat("location_longitude", 0); - Log.i(TAG, "got longitude/latitude from preferences: " + latitude + "/" + longitude); + LOG.info("got longitude/latitude from preferences: {}/{}", latitude, longitude); if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED && getBoolean("use_updated_location_if_available", false)) { @@ -170,7 +171,7 @@ public class GBPrefs extends Prefs { if (lastKnownLocation != null) { latitude = (float) lastKnownLocation.getLatitude(); longitude = (float) lastKnownLocation.getLongitude(); - Log.i(TAG, "got longitude/latitude from last known location: " + latitude + "/" + longitude); + LOG.info("got longitude/latitude from last known location: {}/{}", latitude, longitude); } } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index dd455332cb..bfa1658a60 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -751,6 +751,8 @@ When your watch vibrates, shake the device or press its button. Sleep monitor Write log files + Initialize logging + Click here to try to initialize the logging file Cache weather information Experimental settings Experimental settings might be unstable or not work as expected. Proceed at your own risk. diff --git a/app/src/main/res/xml/debug_preferences_main.xml b/app/src/main/res/xml/debug_preferences_main.xml index 47cb6ea700..ce289d7879 100644 --- a/app/src/main/res/xml/debug_preferences_main.xml +++ b/app/src/main/res/xml/debug_preferences_main.xml @@ -1,6 +1,7 @@ + xmlns:tools="http://schemas.android.com/tools" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + + 5) { - return new File(dirName); - } - fail("Property " + Logging.PROP_LOGFILES_DIR + " has invalid value: " + dirName); - return null; // not reached - } - @Test public void testToggleLogging() { - try { - getLogFilesDir(); - } catch (AssertionError ignored) { - // expected, as not yet set up - } + final Logging logging = Logging.getInstance(); try { - logging.setupLogging(true); - File dir = getLogFilesDir(); - assertEquals(1, dir.list().length); + logging.setFileLoggingEnabled(true); assertNotNull(logging.getFileLogger()); assertTrue(logging.getFileLogger().isStarted()); - logging.setupLogging(false); + logging.setFileLoggingEnabled(false); assertNull(logging.getFileLogger()); - logging.setupLogging(true); + logging.setFileLoggingEnabled(true); assertNotNull(logging.getFileLogger()); assertTrue(logging.getFileLogger().isStarted()); } catch (AssertionError ex) { diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestBase.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestBase.java index 845c1b753b..eff942ff15 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestBase.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/TestBase.java @@ -11,6 +11,7 @@ import org.robolectric.RuntimeEnvironment; import org.robolectric.annotation.Config; import java.io.File; +import java.util.Objects; import ch.qos.logback.classic.util.ContextInitializer; import nodomain.freeyourgadget.gadgetbridge.GBApplication; @@ -20,10 +21,8 @@ import nodomain.freeyourgadget.gadgetbridge.database.DBHandler; import nodomain.freeyourgadget.gadgetbridge.entities.DaoSession; import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice; import nodomain.freeyourgadget.gadgetbridge.model.DeviceType; -import nodomain.freeyourgadget.gadgetbridge.util.FileUtils; import static org.junit.Assert.assertNotNull; -import static nodomain.freeyourgadget.gadgetbridge.Logging.PROP_LOGFILES_DIR; /** * Base class for all testcases in Gadgetbridge that are supposed to run locally @@ -35,31 +34,20 @@ import static nodomain.freeyourgadget.gadgetbridge.Logging.PROP_LOGFILES_DIR; @RunWith(RobolectricTestRunner.class) @Config(sdk = 23, application = GBTestApplication.class) public abstract class TestBase { - protected static File logFilesDir; - protected GBApplication app = (GBApplication) RuntimeEnvironment.application; protected DaoSession daoSession; protected DBHandler dbHandler; // Make sure logging is set up for all testcases, so that we can debug problems @BeforeClass - public static void setupSuite() throws Exception { + public static void setupSuite() { GBEnvironment.setupEnvironment(GBEnvironment.createLocalTestEnvironment()); // print everything going to android.util.Log to System.out System.setProperty("robolectric.logging", "stdout"); - // properties might be preconfigured in build.gradle because of test ordering problems - String logDir = System.getProperty(PROP_LOGFILES_DIR); - if (logDir != null) { - logFilesDir = new File(logDir); - } else { - logFilesDir = FileUtils.createTempDir("logfiles"); - System.setProperty(PROP_LOGFILES_DIR, logFilesDir.getAbsolutePath()); - } - if (System.getProperty(ContextInitializer.CONFIG_FILE_PROPERTY) == null) { - File workingDir = new File(System.getProperty("user.dir")); + File workingDir = new File(Objects.requireNonNull(System.getProperty("user.dir"))); File configFile = new File(workingDir, "src/main/assets/logback.xml"); System.out.println(configFile.getAbsolutePath()); System.setProperty(ContextInitializer.CONFIG_FILE_PROPERTY, configFile.getAbsolutePath()); diff --git a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java index b149f39951..ee92b43199 100644 --- a/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java +++ b/app/src/test/java/nodomain/freeyourgadget/gadgetbridge/test/Tryout.java @@ -6,10 +6,10 @@ import org.slf4j.LoggerFactory; import java.util.GregorianCalendar; -import nodomain.freeyourgadget.gadgetbridge.Logging; import nodomain.freeyourgadget.gadgetbridge.devices.miband.MiBandDateConverter; import nodomain.freeyourgadget.gadgetbridge.service.btle.BLETypeConversions; import nodomain.freeyourgadget.gadgetbridge.util.DateTimeUtils; +import nodomain.freeyourgadget.gadgetbridge.util.GB; /** * A simple class for trying out things, not actually testing something. @@ -22,7 +22,7 @@ public class Tryout extends TestBase { int v = 1 << 7 | 1 << 2; byte b = (byte) v; LOG.info("v: " + v); - Logging.logBytes(LOG, new byte[] { b }); + LOG.warn(GB.hexdump(new byte[] { b })); byte[] bs = new byte[] {(byte) 0xf0,0x28,0x00,0x00 }; LOG.warn("uint32: " + BLETypeConversions.toUint32(bs)); @@ -35,7 +35,7 @@ public class Tryout extends TestBase { GregorianCalendar calendar = MiBandDateConverter.createCalendar(); byte[] bytes = MiBandDateConverter.calendarToRawBytes(calendar,"fake"); LOG.info("Calender: " + DateTimeUtils.formatDateTime(calendar.getTime())); - Logging.logBytes(LOG, bytes); + LOG.warn(GB.hexdump(bytes)); }