commit 4c49986eb10403fd02f206d0bdd22294836f11a2
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Sep 14 23:55:40 2021 +0200

    1) add missing call to BlockController.onPause() / onResume() to the Tutorial activity
    2) rearrange BlockController's error reporting to make the case where the MessageSender thread has died separate
    3) in such case, resurrect the thread
    4) simplify and harden the EffectMessageSender

diff --git a/src/main/java/org/distorted/helpers/BlockController.java b/src/main/java/org/distorted/helpers/BlockController.java
index ea33caa3..53e01049 100644
--- a/src/main/java/org/distorted/helpers/BlockController.java
+++ b/src/main/java/org/distorted/helpers/BlockController.java
@@ -126,20 +126,30 @@ public class BlockController
 
     if( mTouchBlockTime>mPauseTime && touchBlocked>touchThreshhold )
       {
-      TwistyActivity act = mAct.get();
-      boolean reallyBlocked = true;
+      boolean running = EffectMessageSender.isRunning();
 
-      if( act!=null )
+      if( !running )
         {
-        TwistyPreRender pre = act.getTwistyPreRender();
-        if( pre!=null )
+        reportThreadProblem();
+        EffectMessageSender.restartThread();
+        }
+      else
+        {
+        TwistyActivity act = mAct.get();
+        boolean reallyBlocked = true;
+
+        if( act!=null )
           {
-          reallyBlocked = pre.isTouchBlocked();
-          pre.unblockTouch();
+          TwistyPreRender pre = act.getTwistyPreRender();
+          if( pre!=null )
+            {
+            reallyBlocked = pre.isTouchBlocked();
+            pre.unblockTouch();
+            }
           }
-        }
 
-      reportTouchProblem(touchBlocked, reallyBlocked);
+        reportTouchProblem(touchBlocked, reallyBlocked);
+        }
       }
 
     long uiThreshhold = getThreshhold(mLastUIPlace);
@@ -147,20 +157,30 @@ public class BlockController
 
     if( mUIBlockTime>mPauseTime && uiBlocked>uiThreshhold )
       {
-      TwistyActivity act = mAct.get();
-      boolean reallyBlocked = true;
+      boolean running = EffectMessageSender.isRunning();
 
-      if( act!=null )
+      if( !running )
+        {
+        reportThreadProblem();
+        EffectMessageSender.restartThread();
+        }
+      else
         {
-        TwistyPreRender pre = act.getTwistyPreRender();
-        if( pre!=null )
+        TwistyActivity act = mAct.get();
+        boolean reallyBlocked = true;
+
+        if( act!=null )
           {
-          reallyBlocked = !pre.isUINotBlocked();
-          pre.unblockUI();
+          TwistyPreRender pre = act.getTwistyPreRender();
+          if( pre!=null )
+            {
+            reallyBlocked = !pre.isUINotBlocked();
+            pre.unblockUI();
+            }
           }
-        }
 
-      reportUIProblem(uiBlocked, reallyBlocked);
+        reportUIProblem(uiBlocked, reallyBlocked);
+        }
       }
     }
 
@@ -200,7 +220,26 @@ public class BlockController
       FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
       crashlytics.setCustomKey("pause" , mPauseTime );
       crashlytics.setCustomKey("resume", mResumeTime );
-      crashlytics.setCustomKey("thread", EffectMessageSender.reportState() );
+      crashlytics.recordException(ex);
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  private void reportThreadProblem()
+    {
+    String error = EffectMessageSender.reportState();
+
+    if( BuildConfig.DEBUG )
+       {
+       android.util.Log.e("D", error);
+       }
+    else
+      {
+      Exception ex = new Exception(error);
+      FirebaseCrashlytics crashlytics = FirebaseCrashlytics.getInstance();
+      crashlytics.setCustomKey("pause" , mPauseTime );
+      crashlytics.setCustomKey("resume", mResumeTime );
       crashlytics.recordException(ex);
       }
     }
diff --git a/src/main/java/org/distorted/tutorials/TutorialActivity.java b/src/main/java/org/distorted/tutorials/TutorialActivity.java
index ea1c1ec3..a17a0a21 100644
--- a/src/main/java/org/distorted/tutorials/TutorialActivity.java
+++ b/src/main/java/org/distorted/tutorials/TutorialActivity.java
@@ -31,6 +31,7 @@ import android.widget.LinearLayout;
 import com.google.firebase.analytics.FirebaseAnalytics;
 
 import org.distorted.dialogs.RubikDialogError;
+import org.distorted.helpers.BlockController;
 import org.distorted.helpers.TwistyActivity;
 import org.distorted.helpers.TwistyPreRender;
 import org.distorted.library.main.DistortedLibrary;
@@ -188,6 +189,7 @@ public class TutorialActivity extends TwistyActivity
       if( mWebView!=null ) mWebView.onPause();
 
       DistortedLibrary.onPause(1);
+      BlockController.onPause();
       }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -197,6 +199,7 @@ public class TutorialActivity extends TwistyActivity
       {
       super.onResume();
       DistortedLibrary.onResume(1);
+      BlockController.onResume();
       TutorialSurfaceView view = findViewById(R.id.tutorialSurfaceView);
       view.onResume();
       view.initialize();
