diff options
author | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2021-03-21 17:48:45 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-21 17:48:45 +0300 |
commit | 729896a88b17723bf5ee699ae586381cf46d0c64 (patch) | |
tree | 1d93cb0fe802b2004eccabefffbd2119235c0240 | |
parent | 0df58bfd1b8d81943e66e8f077701bbaef7ae236 (diff) |
Make debug-logs accessable
Fix #880 Make debug-logs accessable
10 files changed, 121 insertions, 17 deletions
diff --git a/app/build.gradle b/app/build.gradle index 9a3efff4e..c836f6db2 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -96,6 +96,7 @@ dependencies { implementation 'com.github.stefan-niedermann.nextcloud-commons:sso-glide:1.2.5' implementation 'com.github.stefan-niedermann.nextcloud-commons:exception:1.2.5' implementation 'com.github.stefan-niedermann.android-commons:util:0.2.0' + implementation 'com.github.stefan-niedermann.android-commons:shared-preferences:0.2.0' // Custom Date / Time Picker for branding support implementation 'com.wdullaer:materialdatetimepicker:4.2.3' diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/DeckApplication.java b/app/src/main/java/it/niedermann/nextcloud/deck/DeckApplication.java index 5518e8e9e..cef8ec355 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/DeckApplication.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/DeckApplication.java @@ -17,14 +17,35 @@ public class DeckApplication extends MultiDexApplication { public static final long NO_STACK_ID = -1L; private static String PREF_KEY_THEME; + private static String PREF_KEY_DEBUGGING; @Override public void onCreate() { PREF_KEY_THEME = getString(R.string.pref_key_dark_theme); - setAppTheme(getAppTheme(getApplicationContext())); + PREF_KEY_DEBUGGING = getString(R.string.pref_key_debugging); + setAppTheme(getAppTheme(this)); + DeckLog.enablePeristentLogs(isPersistentLoggingEnabled(this)); super.onCreate(); } + @Override + public void onLowMemory() { + super.onLowMemory(); + DeckLog.clearDebugLog(); + DeckLog.error("--- cleared log because of low memory ---"); + } + + // --------- + // Debugging + // --------- + + public static boolean isPersistentLoggingEnabled(@NonNull Context context) { + final SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context); + boolean enabled = sharedPreferences.getBoolean(PREF_KEY_DEBUGGING, false); + DeckLog.log("--- Read: " + PREF_KEY_DEBUGGING + " | " + enabled); + return enabled; + } + // ----------------- // Day / Night theme // ----------------- diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java b/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java index 47a0385e3..838a69265 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/DeckLog.java @@ -8,8 +8,18 @@ import java.io.PrintWriter; import java.io.StringWriter; public class DeckLog { + + private static final StringBuffer DEBUG_LOG = new StringBuffer(); + private static boolean PERSIST_LOGS = false; private static final String TAG = DeckLog.class.getSimpleName(); + public static void enablePeristentLogs(boolean persistLogs) { + PERSIST_LOGS = persistLogs; + if (!persistLogs) { + clearDebugLog(); + } + } + public enum Severity { VERBOSE, DEBUG, LOG, INFO, WARN, ERROR } @@ -39,17 +49,15 @@ public class DeckLog { } private static void log(String message, Severity severity, int stackTracePosition) { - final String print; - if (BuildConfig.DEBUG) { - final StackTraceElement caller = Thread.currentThread().getStackTrace()[stackTracePosition]; - print = caller.getMethodName() + "() (" + caller.getFileName() + ":" + caller.getLineNumber() + ") → " + message; - } else { - print = message; + if (!(PERSIST_LOGS || BuildConfig.DEBUG)) { + return; + } + final StackTraceElement caller = Thread.currentThread().getStackTrace()[stackTracePosition]; + final String print = caller.getMethodName() + "() (" + caller.getFileName() + ":" + caller.getLineNumber() + ") → " + message; + if (PERSIST_LOGS) { + DEBUG_LOG.append(print).append("\n"); } switch (severity) { - case VERBOSE: - Log.v(TAG, print); - break; case DEBUG: Log.d(TAG, print); break; @@ -106,4 +114,12 @@ public class DeckLog { } return buff.toString(); } + + public static String getDebugLog() { + return DEBUG_LOG.toString(); + } + + public static void clearDebugLog() { + DEBUG_LOG.setLength(0); + } } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java index 877a5d977..b6011b247 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainActivity.java @@ -53,6 +53,7 @@ import java.util.Objects; import it.niedermann.android.crosstabdnd.CrossTabDragAndDrop; import it.niedermann.android.tablayouthelper.TabLayoutHelper; import it.niedermann.android.tablayouthelper.TabTitleGenerator; +import it.niedermann.android.util.ClipboardUtil; import it.niedermann.nextcloud.deck.DeckApplication; import it.niedermann.nextcloud.deck.DeckLog; import it.niedermann.nextcloud.deck.R; @@ -191,6 +192,8 @@ public class MainActivity extends BrandedActivity implements DeleteStackListener binding.navigationView.setNavigationItemSelectedListener(this); sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); + mainViewModel.isDebugModeEnabled().observe(this, (enabled) -> headerBinding.copyDebugLogs.setVisibility(enabled ? View.VISIBLE : View.GONE)); + headerBinding.copyDebugLogs.setOnClickListener((v) -> ClipboardUtil.INSTANCE.copyToClipboard(this, DeckLog.getDebugLog())); switchMap(mainViewModel.hasAccounts(), hasAccounts -> { if (hasAccounts) { return mainViewModel.readAccounts(); @@ -415,6 +418,7 @@ public class MainActivity extends BrandedActivity implements DeleteStackListener headerBinding.headerView.setBackgroundColor(mainColor); @ColorInt final int headerTextColor = contrastRatioIsSufficientBigAreas(mainColor, Color.WHITE) ? Color.WHITE : Color.BLACK; DrawableCompat.setTint(headerBinding.logo.getDrawable(), headerTextColor); + DrawableCompat.setTint(headerBinding.copyDebugLogs.getDrawable(), headerTextColor); headerBinding.appName.setTextColor(headerTextColor); DrawableCompat.setTint(binding.filterIndicator.getDrawable(), getSecondaryForegroundColorDependingOnTheme(this, mainColor)); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java index 62642971e..e7e754034 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/MainViewModel.java @@ -9,10 +9,13 @@ import androidx.core.util.Pair; import androidx.lifecycle.AndroidViewModel; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; +import androidx.preference.PreferenceManager; import java.io.File; import java.util.List; +import it.niedermann.android.sharedpreferences.SharedPreferenceBooleanLiveData; +import it.niedermann.nextcloud.deck.R; import it.niedermann.nextcloud.deck.api.IResponseCallback; import it.niedermann.nextcloud.deck.model.AccessControl; import it.niedermann.nextcloud.deck.model.Account; @@ -48,6 +51,10 @@ public class MainViewModel extends AndroidViewModel { this.syncManager = new SyncManager(application); } + public LiveData<Boolean> isDebugModeEnabled() { + return new SharedPreferenceBooleanLiveData(PreferenceManager.getDefaultSharedPreferences(getApplication()), getApplication().getString(R.string.pref_key_debugging), false); + } + public Account getCurrentAccount() { return currentAccount.getValue(); } diff --git a/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java b/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java index 1cf675f54..abc345bb7 100644 --- a/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java +++ b/app/src/main/java/it/niedermann/nextcloud/deck/ui/settings/SettingsFragment.java @@ -24,6 +24,7 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Brande private BrandedSwitchPreference wifiOnlyPref; private BrandedSwitchPreference brandingPref; private BrandedSwitchPreference compactPref; + private BrandedSwitchPreference debuggingPref; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { @@ -77,6 +78,17 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Brande } else { DeckLog.error("Could not find preference with key: \"" + getString(R.string.pref_key_background_sync) + "\""); } + + debuggingPref = findPreference(getString(R.string.pref_key_debugging)); + if (debuggingPref != null) { + debuggingPref.setOnPreferenceChangeListener((Preference preference, Object newValue) -> { + DeckLog.enablePeristentLogs((Boolean) newValue); + DeckLog.log("persistet debug logs: " + newValue); + return true; + }); + } else { + DeckLog.error("Could not find preference with key: \"" + getString(R.string.pref_key_debugging) + "\""); + } } @Override @@ -93,5 +105,6 @@ public class SettingsFragment extends PreferenceFragmentCompat implements Brande wifiOnlyPref.applyBrand(mainColor); brandingPref.applyBrand(mainColor); compactPref.applyBrand(mainColor); + debuggingPref.applyBrand(mainColor); } } diff --git a/app/src/main/res/layout/nav_header_main.xml b/app/src/main/res/layout/nav_header_main.xml index 34d7cdc7a..182b019ab 100644 --- a/app/src/main/res/layout/nav_header_main.xml +++ b/app/src/main/res/layout/nav_header_main.xml @@ -1,32 +1,59 @@ <?xml version="1.0" encoding="utf-8"?> -<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" android:id="@+id/header_view" android:layout_width="match_parent" android:layout_height="@dimen/drawer_header_height" android:background="@color/defaultBrand"> - <androidx.appcompat.widget.AppCompatImageView + <ImageView android:id="@+id/logo" android:layout_width="@dimen/drawer_header_logo_size" android:layout_height="@dimen/drawer_header_logo_size" - android:layout_centerVertical="true" android:layout_margin="@dimen/spacer_2x" + android:contentDescription="@string/app_logo" android:gravity="center" android:padding="@dimen/spacer_1hx" - android:tint="@android:color/white" - app:srcCompat="@drawable/ic_app_logo" /> + android:src="@drawable/ic_app_logo" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@id/header_view" + app:tint="@android:color/white" /> <TextView android:id="@+id/app_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerVertical="true" + android:layout_marginStart="@dimen/spacer_2x" android:layout_toEndOf="@id/logo" android:ellipsize="end" android:fontFamily="sans-serif-light" android:gravity="center_vertical" android:text="@string/app_name_short" android:textColor="@android:color/white" - android:textSize="24sp" /> -</RelativeLayout>
\ No newline at end of file + android:textSize="24sp" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@+id/logo" + app:layout_constraintTop_toTopOf="parent" /> + + <ImageButton + android:id="@+id/copyDebugLogs" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentEnd="true" + android:layout_centerVertical="true" + android:layout_marginEnd="12dp" + android:background="?attr/selectableItemBackground" + android:contentDescription="@string/copy_logs" + android:padding="@dimen/spacer_2x" + android:src="@drawable/ic_bug_report_black_24dp" + android:tint="@android:color/white" + android:visibility="gone" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:tooltipText="@string/copy_logs" + tools:visibility="visible" /> +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/app/src/main/res/values/setup.xml b/app/src/main/res/values/setup.xml index ae3aad84e..cf67823dc 100644 --- a/app/src/main/res/values/setup.xml +++ b/app/src/main/res/values/setup.xml @@ -10,6 +10,7 @@ <string name="pref_key_branding" translatable="false">branding</string> <string name="pref_key_compact" translatable="false">compact</string> <string name="pref_key_background_sync" translatable="false">backgroundSync</string> + <string name="pref_key_debugging" translatable="false">debugging</string> <string name="pref_value_background_sync_off">off</string> <string name="pref_value_background_15_minutes">15_minutes</string> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index e996d5570..d50fbc23b 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -144,6 +144,7 @@ <string name="settings_theme_title">Theme</string> <string name="settings_branding_title">Branding</string> <string name="settings_compact_title">Compact mode</string> + <string name="settings_debugging">Debug logs</string> <string name="settings_background_sync">Background synchronization</string> <string name="pref_value_wifi_and_mobile">Sync on Wi-Fi and mobile data</string> <string name="pref_value_wifi_only">Sync only on Wi-Fi</string> @@ -323,4 +324,8 @@ <string name="simple_order">Order</string> <string name="edit_description">Edit description</string> <string name="widget_upcoming_title">Upcoming cards</string> + <!-- Category header for a section in the settings which contain features for advanced users --> + <string name="simple_expert_settings">Expert settings</string> + <string name="copy_logs">Copy logs to clipboard</string> + <string name="app_logo">App logo</string> </resources> diff --git a/app/src/main/res/xml/settings.xml b/app/src/main/res/xml/settings.xml index 2b34ae89c..09c4eeaf3 100644 --- a/app/src/main/res/xml/settings.xml +++ b/app/src/main/res/xml/settings.xml @@ -40,4 +40,13 @@ android:title="@string/settings_compact_title" app:defaultValue="false" /> </it.niedermann.nextcloud.deck.ui.branding.BrandedPreferenceCategory> + + <it.niedermann.nextcloud.deck.ui.branding.BrandedPreferenceCategory android:title="@string/simple_expert_settings"> + + <it.niedermann.nextcloud.deck.ui.branding.BrandedSwitchPreference + android:icon="@drawable/ic_bug_report_black_24dp" + android:key="@string/pref_key_debugging" + android:title="@string/settings_debugging" + app:defaultValue="false" /> + </it.niedermann.nextcloud.deck.ui.branding.BrandedPreferenceCategory> </PreferenceScreen> |