commit ac4c7a1d0a12d0de4768aa69b8fabab723b017f3
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Tue Apr 4 14:53:10 2023 +0200

    Separate a OSInterface from LibInterface

diff --git a/src/main/java/org/distorted/bandaged/BandagedOSInterface.java b/src/main/java/org/distorted/bandaged/BandagedOSInterface.java
new file mode 100644
index 00000000..ba5ce8f2
--- /dev/null
+++ b/src/main/java/org/distorted/bandaged/BandagedOSInterface.java
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is proprietary software licensed under an EULA which you should have received      //
+// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.bandaged;
+
+import android.util.DisplayMetrics;
+
+import org.distorted.objectlib.helpers.OperatingSystemInterface;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class BandagedOSInterface implements OperatingSystemInterface
+{
+  private final WeakReference<BandagedPlayActivity> mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  BandagedOSInterface(BandagedPlayActivity act)
+    {
+    mAct = new WeakReference<>(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getScreenDensity()
+    {
+    DisplayMetrics dm = new DisplayMetrics();
+    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
+    return dm.densityDpi;
+    }
+}
diff --git a/src/main/java/org/distorted/bandaged/BandagedPlayView.java b/src/main/java/org/distorted/bandaged/BandagedPlayView.java
index 1e369434..c8529f2f 100644
--- a/src/main/java/org/distorted/bandaged/BandagedPlayView.java
+++ b/src/main/java/org/distorted/bandaged/BandagedPlayView.java
@@ -30,6 +30,7 @@ import static org.distorted.objectlib.main.ObjectControl.MODE_ROTATE;
 public class BandagedPlayView extends GLSurfaceView
 {
     private ObjectControl mObjectController;
+    private BandagedOSInterface mInterface;
     private BandagedPlayRenderer mRenderer;
     private int mScreenWidth, mScreenHeight;
     private boolean mCreated;
@@ -80,7 +81,8 @@ public class BandagedPlayView extends GLSurfaceView
         {
         BandagedPlayActivity act = (BandagedPlayActivity)context;
         BandagedPlayLibInterface ref = new BandagedPlayLibInterface(act);
-        mObjectController = new ObjectControl(ref);
+        mInterface = new BandagedOSInterface(act);
+        mObjectController = new ObjectControl(ref,mInterface);
         mObjectController.setRotateOnCreation(true);
         mRenderer = new BandagedPlayRenderer(this);
 
diff --git a/src/main/java/org/distorted/config/ConfigOSInterface.java b/src/main/java/org/distorted/config/ConfigOSInterface.java
new file mode 100644
index 00000000..b752860e
--- /dev/null
+++ b/src/main/java/org/distorted/config/ConfigOSInterface.java
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is proprietary software licensed under an EULA which you should have received      //
+// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.config;
+
+import android.util.DisplayMetrics;
+
+import org.distorted.objectlib.helpers.OperatingSystemInterface;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class ConfigOSInterface implements OperatingSystemInterface
+{
+  private final WeakReference<ConfigActivity> mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  ConfigOSInterface(ConfigActivity act)
+    {
+    mAct = new WeakReference<>(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getScreenDensity()
+    {
+    DisplayMetrics dm = new DisplayMetrics();
+    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
+    return dm.densityDpi;
+    }
+}
diff --git a/src/main/java/org/distorted/config/ConfigObjectLibInterface.java b/src/main/java/org/distorted/config/ConfigObjectLibInterface.java
index 01aaee55..75eb73c4 100644
--- a/src/main/java/org/distorted/config/ConfigObjectLibInterface.java
+++ b/src/main/java/org/distorted/config/ConfigObjectLibInterface.java
@@ -1,5 +1,5 @@
 ///////////////////////////////////////////////////////////////////////////////////////////////////
-// Copyright 2021 Leszek Koltunski                                                               //
+// Copyright 2023 Leszek Koltunski                                                               //
 //                                                                                               //
 // This file is part of Magic Cube.                                                              //
 //                                                                                               //
@@ -9,8 +9,6 @@
 
 package org.distorted.config;
 
-import android.util.DisplayMetrics;
-
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 import org.distorted.library.message.EffectMessageSender;
@@ -18,16 +16,10 @@ import org.distorted.objectlib.BuildConfig;
 import org.distorted.objectlib.helpers.BlockController;
 import org.distorted.objectlib.helpers.ObjectLibInterface;
 
-import java.lang.ref.WeakReference;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class ConfigObjectLibInterface implements ObjectLibInterface
 {
-  private final WeakReference<ConfigActivity> mAct;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum) { }
   public void onScrambleEffectFinished() { }
   public void onBeginRotation() { }
@@ -135,21 +127,4 @@ public class ConfigObjectLibInterface implements ObjectLibInterface
       case BlockController.TYPE_THREAD    : reportThreadProblem(place,pause,resume,time); break;
       }
     }
-
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  ConfigObjectLibInterface(ConfigActivity act)
-    {
-    mAct = new WeakReference<>(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getScreenDensity()
-    {
-    DisplayMetrics dm = new DisplayMetrics();
-    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
-    return dm.densityDpi;
-    }
 }
diff --git a/src/main/java/org/distorted/config/ConfigSurfaceView.java b/src/main/java/org/distorted/config/ConfigSurfaceView.java
index 5709aeaf..dd2eba35 100644
--- a/src/main/java/org/distorted/config/ConfigSurfaceView.java
+++ b/src/main/java/org/distorted/config/ConfigSurfaceView.java
@@ -26,6 +26,7 @@ import org.distorted.objectlib.main.TwistyObjectNode;
 public class ConfigSurfaceView extends GLSurfaceView
 {
     private ObjectControl mObjectController;
+    private ConfigOSInterface mInterface;
     private ConfigRenderer mRenderer;
     private int mScreenWidth, mScreenHeight;
     private boolean mCreated;
@@ -75,8 +76,9 @@ public class ConfigSurfaceView extends GLSurfaceView
       if(!isInEditMode())
         {
         ConfigActivity act = (ConfigActivity)context;
-        ConfigObjectLibInterface ref = new ConfigObjectLibInterface(act);
-        mObjectController = new ObjectControl(ref);
+        ConfigObjectLibInterface ref = new ConfigObjectLibInterface();
+        mInterface = new ConfigOSInterface(act);
+        mObjectController = new ObjectControl(ref,mInterface);
         mObjectController.setRotateOnCreation(true);
         mRenderer = new ConfigRenderer(this);
 
diff --git a/src/main/java/org/distorted/main/RubikOSInterface.java b/src/main/java/org/distorted/main/RubikOSInterface.java
new file mode 100644
index 00000000..d76d4122
--- /dev/null
+++ b/src/main/java/org/distorted/main/RubikOSInterface.java
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is proprietary software licensed under an EULA which you should have received      //
+// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.main;
+
+import android.util.DisplayMetrics;
+
+import org.distorted.objectlib.helpers.OperatingSystemInterface;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class RubikOSInterface implements OperatingSystemInterface
+{
+  private final WeakReference<RubikActivity> mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  RubikOSInterface(RubikActivity act)
+    {
+    mAct = new WeakReference<>(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getScreenDensity()
+    {
+    DisplayMetrics dm = new DisplayMetrics();
+    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
+    return dm.densityDpi;
+    }
+}
diff --git a/src/main/java/org/distorted/main/RubikObjectLibInterface.java b/src/main/java/org/distorted/main/RubikObjectLibInterface.java
index 8a0faa96..dc2984ba 100644
--- a/src/main/java/org/distorted/main/RubikObjectLibInterface.java
+++ b/src/main/java/org/distorted/main/RubikObjectLibInterface.java
@@ -10,7 +10,6 @@
 package org.distorted.main;
 
 import android.os.Bundle;
-import android.util.DisplayMetrics;
 
 import androidx.annotation.NonNull;
 
@@ -514,13 +513,4 @@ public class RubikObjectLibInterface implements ObjectLibInterface, ListenerOver
     d.setArguments(bundle);
     d.show( act.getSupportFragmentManager(), RubikDialogNewRecord.getDialogTag() );
     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getScreenDensity()
-    {
-    DisplayMetrics dm = new DisplayMetrics();
-    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
-    return dm.densityDpi;
-    }
 }
diff --git a/src/main/java/org/distorted/main/RubikSurfaceView.java b/src/main/java/org/distorted/main/RubikSurfaceView.java
index f8b97410..6d389650 100644
--- a/src/main/java/org/distorted/main/RubikSurfaceView.java
+++ b/src/main/java/org/distorted/main/RubikSurfaceView.java
@@ -33,6 +33,7 @@ import org.distorted.screens.ScreenList;
 public class RubikSurfaceView extends GLSurfaceView
 {
     private ObjectControl mObjectController;
+    private RubikOSInterface mInterface;
     private RubikRenderer mRenderer;
     private int mScreenWidth, mScreenHeight;
     private boolean mCreated;
@@ -111,7 +112,8 @@ public class RubikSurfaceView extends GLSurfaceView
         {
         RubikActivity act = (RubikActivity)context;
         RubikObjectLibInterface ref = new RubikObjectLibInterface(act);
-        mObjectController = new ObjectControl(ref);
+        mInterface = new RubikOSInterface(act);
+        mObjectController = new ObjectControl(ref,mInterface);
         mRenderer = new RubikRenderer(this);
 
         final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
diff --git a/src/main/java/org/distorted/purchase/PurchaseOSInterface.java b/src/main/java/org/distorted/purchase/PurchaseOSInterface.java
new file mode 100644
index 00000000..43fb937b
--- /dev/null
+++ b/src/main/java/org/distorted/purchase/PurchaseOSInterface.java
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is proprietary software licensed under an EULA which you should have received      //
+// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.purchase;
+
+import android.util.DisplayMetrics;
+
+import org.distorted.objectlib.helpers.OperatingSystemInterface;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class PurchaseOSInterface implements OperatingSystemInterface
+{
+  private final WeakReference<PurchaseActivity> mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  PurchaseOSInterface(PurchaseActivity act)
+    {
+    mAct = new WeakReference<>(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getScreenDensity()
+    {
+    DisplayMetrics dm = new DisplayMetrics();
+    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
+    return dm.densityDpi;
+    }
+}
diff --git a/src/main/java/org/distorted/purchase/PurchaseObjectLibInterface.java b/src/main/java/org/distorted/purchase/PurchaseObjectLibInterface.java
index 6ae8e601..d5b521d3 100644
--- a/src/main/java/org/distorted/purchase/PurchaseObjectLibInterface.java
+++ b/src/main/java/org/distorted/purchase/PurchaseObjectLibInterface.java
@@ -9,30 +9,15 @@
 
 package org.distorted.purchase;
 
-import android.util.DisplayMetrics;
-
 import com.google.firebase.crashlytics.FirebaseCrashlytics;
 
 import org.distorted.objectlib.BuildConfig;
 import org.distorted.objectlib.helpers.ObjectLibInterface;
 
-import java.lang.ref.WeakReference;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class PurchaseObjectLibInterface implements ObjectLibInterface
 {
-  private final WeakReference<PurchaseActivity> mAct;
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  PurchaseObjectLibInterface(PurchaseActivity act)
-    {
-    mAct = new WeakReference<>(act);
-    }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
   public void onWinEffectFinished(long startTime, long endTime, String debug, int scrambleNum) { }
   public void onScrambleEffectFinished() { }
   public void onBeginRotation() { }
@@ -69,13 +54,4 @@ public class PurchaseObjectLibInterface implements ObjectLibInterface
         }
       }
     }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getScreenDensity()
-    {
-    DisplayMetrics dm = new DisplayMetrics();
-    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
-    return dm.densityDpi;
-    }
 }
diff --git a/src/main/java/org/distorted/purchase/PurchaseSurfaceView.java b/src/main/java/org/distorted/purchase/PurchaseSurfaceView.java
index cfc3ce98..0c4e15e0 100644
--- a/src/main/java/org/distorted/purchase/PurchaseSurfaceView.java
+++ b/src/main/java/org/distorted/purchase/PurchaseSurfaceView.java
@@ -26,6 +26,7 @@ import org.distorted.objectlib.main.TwistyObjectNode;
 public class PurchaseSurfaceView extends GLSurfaceView
 {
     private ObjectControl mObjectController;
+    private PurchaseOSInterface mInterface;
     private PurchaseRenderer mRenderer;
     private boolean mCreated;
 
@@ -72,8 +73,9 @@ public class PurchaseSurfaceView extends GLSurfaceView
       if(!isInEditMode())
         {
         PurchaseActivity act = (PurchaseActivity)context;
-        PurchaseObjectLibInterface ref = new PurchaseObjectLibInterface(act);
-        mObjectController = new ObjectControl(ref);
+        PurchaseObjectLibInterface ref = new PurchaseObjectLibInterface();
+        mInterface = new PurchaseOSInterface(act);
+        mObjectController = new ObjectControl(ref,mInterface);
         mObjectController.setRotateOnCreation(true);
         mRenderer = new PurchaseRenderer(this);
 
diff --git a/src/main/java/org/distorted/tutorials/TutorialOSInterface.java b/src/main/java/org/distorted/tutorials/TutorialOSInterface.java
new file mode 100644
index 00000000..b5ee7498
--- /dev/null
+++ b/src/main/java/org/distorted/tutorials/TutorialOSInterface.java
@@ -0,0 +1,39 @@
+///////////////////////////////////////////////////////////////////////////////////////////////////
+// Copyright 2023 Leszek Koltunski                                                               //
+//                                                                                               //
+// This file is part of Magic Cube.                                                              //
+//                                                                                               //
+// Magic Cube is proprietary software licensed under an EULA which you should have received      //
+// along with the code. If not, check https://distorted.org/magic/License-Magic-Cube.html        //
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+package org.distorted.tutorials;
+
+import android.util.DisplayMetrics;
+
+import org.distorted.objectlib.helpers.OperatingSystemInterface;
+
+import java.lang.ref.WeakReference;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+public class TutorialOSInterface implements OperatingSystemInterface
+{
+  private final WeakReference<TutorialActivity> mAct;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  TutorialOSInterface(TutorialActivity act)
+    {
+    mAct = new WeakReference<>(act);
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public int getScreenDensity()
+    {
+    DisplayMetrics dm = new DisplayMetrics();
+    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
+    return dm.densityDpi;
+    }
+}
diff --git a/src/main/java/org/distorted/tutorials/TutorialObjectLibInterface.java b/src/main/java/org/distorted/tutorials/TutorialObjectLibInterface.java
index 371bf536..7d1d916f 100644
--- a/src/main/java/org/distorted/tutorials/TutorialObjectLibInterface.java
+++ b/src/main/java/org/distorted/tutorials/TutorialObjectLibInterface.java
@@ -158,13 +158,4 @@ public class TutorialObjectLibInterface implements ObjectLibInterface
      TutorialScreen state = act.getState();
      state.reddenLock(act);
      }
-
-///////////////////////////////////////////////////////////////////////////////////////////////////
-
-  public int getScreenDensity()
-    {
-    DisplayMetrics dm = new DisplayMetrics();
-    mAct.get().getWindowManager().getDefaultDisplay().getMetrics(dm);
-    return dm.densityDpi;
-    }
 }
diff --git a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
index 93e81560..65070274 100644
--- a/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
+++ b/src/main/java/org/distorted/tutorials/TutorialSurfaceView.java
@@ -29,6 +29,7 @@ import static org.distorted.objectlib.main.ObjectControl.MODE_DRAG;
 public class TutorialSurfaceView extends GLSurfaceView
 {
     private ObjectControl mObjectController;
+    private TutorialOSInterface mInterface;
     private TutorialRenderer mRenderer;
     private int mScreenWidth, mScreenHeight;
     private boolean mCreated;
@@ -85,7 +86,8 @@ public class TutorialSurfaceView extends GLSurfaceView
         {
         TutorialActivity act = (TutorialActivity)context;
         TutorialObjectLibInterface ref = new TutorialObjectLibInterface(act);
-        mObjectController = new ObjectControl(ref);
+        mInterface = new TutorialOSInterface(act);
+        mObjectController = new ObjectControl(ref,mInterface);
         mRenderer = new TutorialRenderer(this);
 
         final ActivityManager activityManager= (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
