mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge.git
synced 2026-07-31 07:44:24 +02:00
Replace android.util.Log with logback
This commit is contained in:
@@ -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<String> 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<String>) 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<String> 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<String>) 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);
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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<ILoggingEvent> 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<ILoggingEvent> 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<ILoggingEvent> logger) {
|
||||
private static void attachLogger(final Appender<ILoggingEvent> 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<ILoggingEvent> logger) {
|
||||
private static void detachLogger(final Appender<ILoggingEvent> 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<ILoggingEvent> 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<ILoggingEvent> 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<ILoggingEvent> fileAppender = new RollingFileAppender<ILoggingEvent>();
|
||||
final SizeAndTimeBasedRollingPolicy<ILoggingEvent> rollingPolicy = new SizeAndTimeBasedRollingPolicy<>();
|
||||
final RollingFileAppender<ILoggingEvent> fileAppender = new RollingFileAppender<>();
|
||||
|
||||
rollingPolicy.setContext(lc);
|
||||
rollingPolicy.setFileNamePattern(logDirectory + "/gadgetbridge-%d{yyyy-MM-dd}.%i.log.zip");
|
||||
|
||||
+26
-8
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -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"
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ class DatabaseTableDebugFragment : AbstractDebugFragment() {
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
GB.log("Error accessing database", GB.ERROR, e)
|
||||
LOG.error("Error accessing database", e)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+31
-9
@@ -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<SwitchPreferenceCompat>(LOG_TO_FILE)?.let {
|
||||
val logToFilePreference = findPreference<SwitchPreferenceCompat>(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<Preference?>("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"
|
||||
|
||||
+6
-5
@@ -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);
|
||||
|
||||
+6
-2
@@ -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();
|
||||
}
|
||||
|
||||
-12
@@ -16,8 +16,6 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
+16
-14
@@ -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()) {
|
||||
|
||||
+10
-10
@@ -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<NotificationConfiguration> 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<NotificationConfiguration> {
|
||||
PackageManager manager;
|
||||
|
||||
PackageAdapter(@NonNull Context context, int resource, @NonNull List<NotificationConfiguration> 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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
+49
-46
@@ -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<Device> 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-9
@@ -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 {
|
||||
|
||||
+3
-13
@@ -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) {
|
||||
|
||||
+6
-7
@@ -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)
|
||||
|
||||
-5
@@ -16,21 +16,16 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
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 {
|
||||
|
||||
|
||||
+1
-2
@@ -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(){
|
||||
|
||||
-8
@@ -16,16 +16,8 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
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;
|
||||
|
||||
|
||||
+7
-12
@@ -16,8 +16,6 @@
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>. */
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
-1
@@ -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;
|
||||
|
||||
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<String> 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<File> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -751,6 +751,8 @@
|
||||
<string name="watch9_pairing_tap_hint">When your watch vibrates, shake the device or press its button.</string>
|
||||
<string name="title_activity_sleepmonitor">Sleep monitor</string>
|
||||
<string name="pref_write_logfiles">Write log files</string>
|
||||
<string name="pref_restart_logging_title">Initialize logging</string>
|
||||
<string name="pref_restart_logging_summary">Click here to try to initialize the logging file</string>
|
||||
<string name="pref_cache_weather">Cache weather information</string>
|
||||
<string name="pref_experimental_settings_title">Experimental settings</string>
|
||||
<string name="pref_experimental_settings_summary">Experimental settings might be unstable or not work as expected. Proceed at your own risk.</string>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_add"
|
||||
@@ -19,6 +20,13 @@
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_write_logfiles" />
|
||||
|
||||
<Preference
|
||||
android:icon="@drawable/ic_refresh"
|
||||
android:key="log_restart"
|
||||
android:summary="@string/pref_restart_logging_summary"
|
||||
android:title="@string/pref_restart_logging_title"
|
||||
app:isPreferenceVisible="false" />
|
||||
|
||||
<Preference
|
||||
android:dependency="log_to_file"
|
||||
android:icon="@drawable/ic_share"
|
||||
|
||||
@@ -368,6 +368,12 @@
|
||||
android:layout="@layout/preference_checkbox"
|
||||
android:title="@string/pref_write_logfiles"
|
||||
app:iconSpaceReserved="false" />
|
||||
<Preference
|
||||
android:key="log_restart"
|
||||
android:summary="@string/pref_restart_logging_summary"
|
||||
android:title="@string/pref_restart_logging_title"
|
||||
app:iconSpaceReserved="false"
|
||||
app:isPreferenceVisible="false" />
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="crash_notification"
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.test;
|
||||
|
||||
import android.util.Log;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
|
||||
public class GBTestApplication extends GBApplication {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(GBTestApplication.class);
|
||||
|
||||
@Override
|
||||
protected void migratePrefsIfNeeded() {
|
||||
// In tests, do not migrate preferences
|
||||
// FIXME: This is not ideal. In tests, do not migrate preferences. We should be able to initialize
|
||||
// the database before the application is created so that this works and is actually testable., but
|
||||
// right now all it does is spam the logs with dozens of stack traces for failed preference migrations
|
||||
Log.i("GBTestApplication", "Skipping preference migration during tests");
|
||||
LOG.info("Skipping preference migration during tests");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
package nodomain.freeyourgadget.gadgetbridge.test;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.Logging;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
/**
|
||||
* Tests dynamic enablement and disablement of file appenders.
|
||||
@@ -24,44 +17,19 @@ public class LoggingTest extends TestBase {
|
||||
public LoggingTest() {
|
||||
}
|
||||
|
||||
private Logging logging = GBApplication.getLogging();
|
||||
|
||||
@Override
|
||||
@After
|
||||
public void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
assertTrue(FileUtils.deleteRecursively(getLogFilesDir()));
|
||||
}
|
||||
|
||||
@NonNull
|
||||
private File getLogFilesDir() {
|
||||
String dirName = System.getProperty(Logging.PROP_LOGFILES_DIR);
|
||||
if (dirName != null && dirName.length() > 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) {
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user