commit 7fe62d1f810d79976202a81945018b21f54cdf29
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Jan 29 23:45:29 2022 +0100

    Download the icons only once and save to local storage.

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
index 6152163f..2cbe325f 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
@@ -19,6 +19,8 @@
 
 package org.distorted.dialogs;
 
+import java.lang.ref.WeakReference;
+
 import android.app.Activity;
 import android.graphics.Bitmap;
 import android.graphics.Color;
@@ -36,9 +38,6 @@ import org.distorted.external.RubikNetwork;
 import org.distorted.external.RubikUpdates;
 import org.distorted.objects.RubikObjectList;
 
-import java.io.IOException;
-import java.lang.ref.WeakReference;
-
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikDialogUpdateView implements RubikNetwork.Downloadee
@@ -48,14 +47,15 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
   private ProgressBar mBar;
   private Button mButton;
   private TextView mDescription;
-
   private WeakReference<Activity> mAct;
+  private boolean mIconSaved;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public View createView(Activity act, RubikUpdates.UpdateInfo info, int fontSize, int padding,
                          LinearLayout.LayoutParams pView, LinearLayout.LayoutParams pText, LinearLayout.LayoutParams pButt )
     {
+    mIconSaved=false;
     mAct = new WeakReference<>(act);
     mInfo = info;
     final RubikNetwork.Downloadee downloadee = this;
@@ -111,9 +111,17 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  void setIcon(Bitmap icon)
+  void setIcon(Bitmap icon, boolean downloaded)
     {
     mIcon.setImageBitmap(icon);
+
+    if( downloaded )
+      {
+      String name = mInfo.mObjectShortName + ".png";
+      Activity act = mAct.get();
+      RubikFiles files = RubikFiles.getInstance();
+      mIconSaved = files.saveIcon(act,mInfo.mIcon, name);
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
@@ -141,14 +149,7 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
       mDescription.setText(R.string.installing);
 
       RubikFiles files = RubikFiles.getInstance();
-      boolean iSuccess=true,oSuccess=true, eSuccess=true;
-
-      if( mInfo.mIcon!=null )
-        {
-        String name = mInfo.mObjectShortName + ".png";
-        Activity act = mAct.get();
-        iSuccess = files.saveFile(act,mInfo.mIcon, name);
-        }
+      boolean oSuccess=true, eSuccess=true;
 
       if( mInfo.mObjectStream!=null )
         {
@@ -164,11 +165,11 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
         eSuccess = files.saveFile(act,mInfo.mExtrasStream, name);
         }
 
-      if( iSuccess && oSuccess )
+      if( mIconSaved || oSuccess || eSuccess )
         {
         mBar.setProgress(75);
         mDescription.setText(R.string.configuring);
-        RubikObjectList.addDownloadedObject(mInfo.mObjectShortName,iSuccess,oSuccess,eSuccess);
+        RubikObjectList.addDownloadedObject(mInfo.mObjectShortName,mIconSaved,oSuccess,eSuccess);
         mBar.setProgress(100);
         mDescription.setText(R.string.success);
 
diff --git a/src/main/java/org/distorted/dialogs/RubikDialogUpdates.java b/src/main/java/org/distorted/dialogs/RubikDialogUpdates.java
index f4cec98e..00049ec9 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogUpdates.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogUpdates.java
@@ -186,7 +186,7 @@ public class RubikDialogUpdates extends AppCompatDialogFragment implements Rubik
           }
 
         RubikNetwork network = RubikNetwork.getInstance();
-        network.downloadIcons(this);
+        network.downloadIcons(act,this);
         }
       else
         {
@@ -224,7 +224,7 @@ public class RubikDialogUpdates extends AppCompatDialogFragment implements Rubik
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void iconDownloaded(int ordinal, Bitmap icon)
+  public void iconDownloaded(int ordinal, Bitmap icon, boolean downloaded)
     {
     FragmentActivity act = getActivity();
 
@@ -236,7 +236,7 @@ public class RubikDialogUpdates extends AppCompatDialogFragment implements Rubik
         public void run()
           {
           RubikDialogUpdateView view = mPanes.get(ordinal);
-          if( view!=null ) view.setIcon(icon);
+          if( view!=null ) view.setIcon(icon,downloaded);
           }
         });
       }
diff --git a/src/main/java/org/distorted/external/RubikFiles.java b/src/main/java/org/distorted/external/RubikFiles.java
index abb773f3..2f3235b8 100644
--- a/src/main/java/org/distorted/external/RubikFiles.java
+++ b/src/main/java/org/distorted/external/RubikFiles.java
@@ -27,6 +27,7 @@ import java.io.OutputStream;
 
 import android.content.Context;
 import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -51,6 +52,21 @@ public class RubikFiles
     return mThis;
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public Bitmap getIcon(Context context, String name)
+    {
+    File file = new File(context.getFilesDir(), name);
+
+    if( file.exists() )
+      {
+      String fname = context.getFilesDir().getAbsolutePath()+"/"+name;
+      return BitmapFactory.decodeFile(fname);
+      }
+
+    return null;
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public boolean saveFile(Context context, InputStream stream, String name)
@@ -79,7 +95,7 @@ public class RubikFiles
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public boolean saveFile(Context context, Bitmap bmp, String name)
+  public boolean saveIcon(Context context, Bitmap bmp, String name)
     {
     try
       {
diff --git a/src/main/java/org/distorted/external/RubikNetwork.java b/src/main/java/org/distorted/external/RubikNetwork.java
index b637e74b..b39aae02 100644
--- a/src/main/java/org/distorted/external/RubikNetwork.java
+++ b/src/main/java/org/distorted/external/RubikNetwork.java
@@ -29,6 +29,7 @@ import java.net.UnknownHostException;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
+import android.content.Context;
 import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.graphics.Bitmap;
@@ -55,7 +56,7 @@ public class RubikNetwork
 
   public interface IconReceiver
     {
-    void iconDownloaded(int ordinal, Bitmap bitmap);
+    void iconDownloaded(int ordinal, Bitmap bitmap, boolean downloaded);
     }
 
   public interface Updatee
@@ -693,7 +694,7 @@ public class RubikNetwork
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  private void iconThread(IconReceiver receiver)
+  private void iconThread(Context context, IconReceiver receiver)
     {
     int numC = mUpdates.getCompletedNumber();
     int numS = mUpdates.getStartedNumber();
@@ -704,17 +705,19 @@ public class RubikNetwork
 
       if( iconPresent!=0 )
         {
-        Bitmap icon = mUpdates.getCompletedIcon(c);
+        boolean downloaded = false;
+        Bitmap icon = mUpdates.getCompletedIcon(context,c);
 
         if( icon==null )
           {
           String url = mUpdates.getCompletedURL(c);
           icon = downloadIcon(url);
+          downloaded = true;
           }
         if( icon!=null )
           {
           mUpdates.setCompletedIcon(c,icon);
-          receiver.iconDownloaded(c,icon);
+          receiver.iconDownloaded(c,icon,downloaded);
           }
         }
       }
@@ -725,17 +728,19 @@ public class RubikNetwork
 
       if( iconPresent!=0 )
         {
-        Bitmap icon = mUpdates.getStartedIcon(s);
+        boolean downloaded = false;
+        Bitmap icon = mUpdates.getStartedIcon(context,s);
 
         if( icon==null )
           {
           String url = mUpdates.getStartedURL(s);
           icon = downloadIcon(url);
+          downloaded = true;
           }
         if( icon!=null )
           {
           mUpdates.setStartedIcon(s,icon);
-          receiver.iconDownloaded(numC+s,icon);
+          receiver.iconDownloaded(numC+s,icon,downloaded);
           }
         }
       }
@@ -905,7 +910,7 @@ public class RubikNetwork
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public void downloadIcons(final IconReceiver receiver)
+  public void downloadIcons(final Context context, final IconReceiver receiver)
     {
     initializeStatics();
 
@@ -913,7 +918,7 @@ public class RubikNetwork
       {
       public void run()
         {
-        iconThread(receiver);
+        iconThread(context,receiver);
         }
       };
 
diff --git a/src/main/java/org/distorted/external/RubikUpdates.java b/src/main/java/org/distorted/external/RubikUpdates.java
index d65c8316..380af597 100644
--- a/src/main/java/org/distorted/external/RubikUpdates.java
+++ b/src/main/java/org/distorted/external/RubikUpdates.java
@@ -21,6 +21,8 @@ package org.distorted.external;
 
 import java.io.InputStream;
 import java.util.ArrayList;
+
+import android.content.Context;
 import android.graphics.Bitmap;
 import org.distorted.objects.RubikObjectList;
 
@@ -158,7 +160,7 @@ public class RubikUpdates
 
   public void updateDone(String shortName)
     {
-    for( UpdateInfo info : mCompleted)
+    for( UpdateInfo info : mCompleted )
       {
       if( info.mObjectShortName.equals(shortName) )
         {
@@ -198,16 +200,30 @@ public class RubikUpdates
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public Bitmap getCompletedIcon(int ordinal)
+  public Bitmap getCompletedIcon(Context context, int ordinal)
     {
-    return mCompleted.get(ordinal).mIcon;
+    UpdateInfo info = mCompleted.get(ordinal);
+    Bitmap bmp = info.mIcon;
+    if( bmp!=null ) return bmp;
+
+    RubikFiles files = RubikFiles.getInstance();
+    bmp = files.getIcon(context,info.mObjectShortName+".png");
+    info.mIcon = bmp;
+    return bmp;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public Bitmap getStartedIcon(int ordinal)
+  public Bitmap getStartedIcon(Context context, int ordinal)
     {
-    return mStarted.get(ordinal).mIcon;
+    UpdateInfo info = mStarted.get(ordinal);
+    Bitmap bmp = info.mIcon;
+    if( bmp!=null ) return bmp;
+
+    RubikFiles files = RubikFiles.getInstance();
+    bmp = files.getIcon(context,info.mObjectShortName+".png");
+    info.mIcon = bmp;
+    return bmp;
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/solvers/SolverMain.java b/src/main/java/org/distorted/solvers/SolverMain.java
index 0deadd1c..c999dd23 100644
--- a/src/main/java/org/distorted/solvers/SolverMain.java
+++ b/src/main/java/org/distorted/solvers/SolverMain.java
@@ -125,7 +125,7 @@ public class SolverMain implements Runnable
         }
       }
 
-    if( cubit>19) return 4;
+    if( cubit>19 ) return 4;
 
     switch(face)
       {
