diff --git a/app/src/main/java/eu/faircode/email/ActivityBase.java b/app/src/main/java/eu/faircode/email/ActivityBase.java index c1a9e6dd45..8b22bdf6e1 100644 --- a/app/src/main/java/eu/faircode/email/ActivityBase.java +++ b/app/src/main/java/eu/faircode/email/ActivityBase.java @@ -35,6 +35,7 @@ import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.PowerManager; +import android.os.SystemClock; import android.text.TextUtils; import android.view.KeyEvent; import android.view.MenuItem; @@ -49,6 +50,8 @@ import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; import androidx.core.content.FileProvider; import androidx.documentfile.provider.DocumentFile; +import androidx.fragment.app.Fragment; +import androidx.fragment.app.FragmentManager; import androidx.lifecycle.Lifecycle; import androidx.lifecycle.LifecycleObserver; import androidx.lifecycle.LifecycleOwner; @@ -89,6 +92,8 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc EntityLog.log(this, intent + " extras=" + TextUtils.join(", ", Log.getExtras(intent.getExtras()))); + getSupportFragmentManager().registerFragmentLifecycleCallbacks(lifecycleCallbacks, true); + this.contacts = hasPermission(Manifest.permission.READ_CONTACTS); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); @@ -639,6 +644,87 @@ abstract class ActivityBase extends AppCompatActivity implements SharedPreferenc return ApplicationEx.getMainHandler(); } + private final FragmentManager.FragmentLifecycleCallbacks lifecycleCallbacks = new FragmentManager.FragmentLifecycleCallbacks() { + private long last = 0; + + @Override + public void onFragmentPreAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) { + log(fm, f, "onFragmentPreAttached"); + } + + @Override + public void onFragmentAttached(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Context context) { + log(fm, f, "onFragmentAttached"); + } + + @Override + public void onFragmentPreCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + log(fm, f, "onFragmentPreCreated"); + } + + @Override + public void onFragmentCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + log(fm, f, "onFragmentCreated"); + } + + @Override + public void onFragmentActivityCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + log(fm, f, "onFragmentActivityCreated"); + } + + @Override + public void onFragmentViewCreated(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull View v, @Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) { + log(fm, f, "onFragmentViewCreated"); + } + + @Override + public void onFragmentStarted(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentStarted"); + } + + @Override + public void onFragmentResumed(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentResumed"); + } + + @Override + public void onFragmentPaused(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentPaused"); + } + + @Override + public void onFragmentStopped(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentStopped"); + } + + @Override + public void onFragmentSaveInstanceState(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull Bundle outState) { + log(fm, f, "onFragmentSaveInstanceState"); + } + + @Override + public void onFragmentViewDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentViewDestroyed"); + } + + @Override + public void onFragmentDestroyed(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentDestroyed"); + } + + @Override + public void onFragmentDetached(@NonNull FragmentManager fm, @NonNull Fragment f) { + log(fm, f, "onFragmentDetached"); + } + + private void log(@NonNull FragmentManager fm, @NonNull Fragment f, @NonNull String what) { + long start = last; + last = SystemClock.elapsedRealtime(); + long elapsed = (start == 0 ? 0 : last - start); + Log.i(f.getClass().getSimpleName() + " " + what + " " + elapsed + " ms"); + } + }; + public interface IKeyPressedListener { boolean onKeyPressed(KeyEvent event); diff --git a/app/src/main/java/eu/faircode/email/ApplicationEx.java b/app/src/main/java/eu/faircode/email/ApplicationEx.java index 864c0b9aec..e797030e52 100644 --- a/app/src/main/java/eu/faircode/email/ApplicationEx.java +++ b/app/src/main/java/eu/faircode/email/ApplicationEx.java @@ -19,6 +19,7 @@ package eu.faircode.email; Copyright 2018-2021 by Marcel Bokhorst (M66B) */ +import android.app.Activity; import android.app.Application; import android.content.BroadcastReceiver; import android.content.Context; @@ -27,14 +28,17 @@ import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.Configuration; import android.os.Build; +import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.os.StrictMode; +import android.os.SystemClock; import android.os.strictmode.Violation; import android.util.Printer; import android.webkit.CookieManager; import androidx.annotation.NonNull; +import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; import androidx.work.WorkManager; @@ -97,6 +101,8 @@ public class ApplicationEx extends Application " process=" + android.os.Process.myPid()); Log.logMemory(this, "App"); + registerActivityLifecycleCallbacks(lifecycleCallbacks); + getMainLooper().setMessageLogging(new Printer() { @Override public void println(String msg) { @@ -511,6 +517,122 @@ public class ApplicationEx extends Application editor.apply(); } + private final ActivityLifecycleCallbacks lifecycleCallbacks = new ActivityLifecycleCallbacks() { + private long last = 0; + + @Override + public void onActivityPreCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + log(activity, "onActivityPreCreated"); + } + + @Override + public void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + log(activity, "onActivityCreated"); + } + + @Override + public void onActivityPostCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState) { + log(activity, "onActivityPostCreated"); + } + + @Override + public void onActivityPreStarted(@NonNull Activity activity) { + log(activity, "onActivityPreStarted"); + } + + @Override + public void onActivityStarted(@NonNull Activity activity) { + log(activity, "onActivityStarted"); + } + + @Override + public void onActivityPostStarted(@NonNull Activity activity) { + log(activity, "onActivityPostStarted"); + } + + @Override + public void onActivityPreResumed(@NonNull Activity activity) { + log(activity, "onActivityPreResumed"); + } + + @Override + public void onActivityResumed(@NonNull Activity activity) { + log(activity, "onActivityResumed"); + } + + @Override + public void onActivityPostResumed(@NonNull Activity activity) { + log(activity, "onActivityPostResumed"); + } + + @Override + public void onActivityPrePaused(@NonNull Activity activity) { + log(activity, "onActivityPrePaused"); + } + + @Override + public void onActivityPaused(@NonNull Activity activity) { + log(activity, "onActivityPaused"); + } + + @Override + public void onActivityPostPaused(@NonNull Activity activity) { + log(activity, "onActivityPostPaused"); + } + + @Override + public void onActivityPreStopped(@NonNull Activity activity) { + log(activity, "onActivityPreStopped"); + } + + @Override + public void onActivityStopped(@NonNull Activity activity) { + log(activity, "onActivityStopped"); + } + + @Override + public void onActivityPostStopped(@NonNull Activity activity) { + log(activity, "onActivityPostStopped"); + } + + @Override + public void onActivityPreSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { + log(activity, "onActivityPreSaveInstanceState"); + } + + @Override + public void onActivitySaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { + log(activity, "onActivitySaveInstanceState"); + } + + @Override + public void onActivityPostSaveInstanceState(@NonNull Activity activity, @NonNull Bundle outState) { + log(activity, "onActivityPostSaveInstanceState"); + } + + @Override + public void onActivityPreDestroyed(@NonNull Activity activity) { + log(activity, "onActivityPreDestroyed"); + } + + @Override + public void onActivityDestroyed(@NonNull Activity activity) { + log(activity, "onActivityDestroyed"); + } + + @Override + public void onActivityPostDestroyed(@NonNull Activity activity) { + log(activity, "onActivityPostDestroyed"); + } + + private void log(@NonNull Activity activity, @NonNull String what) { + long start = last; + last = SystemClock.elapsedRealtime(); + long elapsed = (start == 0 ? 0 : last - start); + Log.i(activity.getClass().getSimpleName() + " " + what + " " + elapsed + " ms"); + } + }; + private final BroadcastReceiver onScreenOff = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) {