commit 806329e37d0ae3134f800151853c191a69a46ee5
Author: Leszek Koltunski <leszek@koltunski.pl>
Date:   Sat Jan 29 00:13:12 2022 +0100

    Support for saving the downloaded JSONs in local data storage.

diff --git a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
index 703750dc..6152163f 100644
--- a/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
+++ b/src/main/java/org/distorted/dialogs/RubikDialogUpdateView.java
@@ -34,6 +34,10 @@ import org.distorted.external.RubikFiles;
 import org.distorted.main.R;
 import org.distorted.external.RubikNetwork;
 import org.distorted.external.RubikUpdates;
+import org.distorted.objects.RubikObjectList;
+
+import java.io.IOException;
+import java.lang.ref.WeakReference;
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
@@ -45,11 +49,14 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
   private Button mButton;
   private TextView mDescription;
 
+  private WeakReference<Activity> mAct;
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public View createView(Activity act, RubikUpdates.UpdateInfo info, int fontSize, int padding,
                          LinearLayout.LayoutParams pView, LinearLayout.LayoutParams pText, LinearLayout.LayoutParams pButt )
     {
+    mAct = new WeakReference<>(act);
     mInfo = info;
     final RubikNetwork.Downloadee downloadee = this;
     View view = act.getLayoutInflater().inflate(R.layout.dialog_updates_pane, null);
@@ -134,24 +141,39 @@ public class RubikDialogUpdateView implements RubikNetwork.Downloadee
       mDescription.setText(R.string.installing);
 
       RubikFiles files = RubikFiles.getInstance();
-      boolean oSuccess=true, eSuccess=true;
+      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);
+        }
 
       if( mInfo.mObjectStream!=null )
         {
         String name = mInfo.mObjectShortName + "_object.json";
-        oSuccess = files.saveFile(mInfo.mObjectStream, name);
+        Activity act = mAct.get();
+        oSuccess = files.saveFile(act,mInfo.mObjectStream, name);
         }
 
       if( mInfo.mExtrasStream!=null )
         {
         String name = mInfo.mObjectShortName + "_extras.json";
-        eSuccess = files.saveFile(mInfo.mExtrasStream, name);
+        Activity act = mAct.get();
+        eSuccess = files.saveFile(act,mInfo.mExtrasStream, name);
         }
 
-      if( oSuccess )
+      if( iSuccess && oSuccess )
         {
         mBar.setProgress(75);
         mDescription.setText(R.string.configuring);
+        RubikObjectList.addDownloadedObject(mInfo.mObjectShortName,iSuccess,oSuccess,eSuccess);
+        mBar.setProgress(100);
+        mDescription.setText(R.string.success);
+
+        RubikNetwork network = RubikNetwork.getInstance();
+        network.updateDone(mInfo.mObjectShortName);
         }
       else
         {
diff --git a/src/main/java/org/distorted/external/RubikFiles.java b/src/main/java/org/distorted/external/RubikFiles.java
index d321b14c..abb773f3 100644
--- a/src/main/java/org/distorted/external/RubikFiles.java
+++ b/src/main/java/org/distorted/external/RubikFiles.java
@@ -19,7 +19,16 @@
 
 package org.distorted.external;
 
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.io.OutputStream;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class RubikFiles
   {
@@ -44,8 +53,47 @@ public class RubikFiles
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-  public boolean saveFile(InputStream stream, String name)
+  public boolean saveFile(Context context, InputStream stream, String name)
     {
-    return false;
+    try
+      {
+      File file = new File(context.getFilesDir(), name);
+      OutputStream outStream = new FileOutputStream(file);
+
+      byte[] buffer = new byte[8*1024];
+      int bytesRead;
+      while ((bytesRead = stream.read(buffer)) != -1)
+        {
+        outStream.write(buffer, 0, bytesRead);
+        }
+      outStream.close();
+
+      return true;
+      }
+    catch(IOException ioe)
+      {
+      android.util.Log.e("D", "Exception trying to save "+name+" : "+ioe.getMessage() );
+      return false;
+      }
+    }
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public boolean saveFile(Context context, Bitmap bmp, String name)
+    {
+    try
+      {
+      File file = new File(context.getFilesDir(), name);
+      OutputStream outStream = new FileOutputStream(file);
+      bmp.compress(Bitmap.CompressFormat.PNG, 100, outStream);
+      outStream.close();
+
+      return true;
+      }
+    catch(IOException ioe)
+      {
+      android.util.Log.e("D", "Exception trying to save "+name+" : "+ioe.getMessage() );
+      return false;
+      }
     }
   }
diff --git a/src/main/java/org/distorted/external/RubikNetwork.java b/src/main/java/org/distorted/external/RubikNetwork.java
index 362e0d75..b637e74b 100644
--- a/src/main/java/org/distorted/external/RubikNetwork.java
+++ b/src/main/java/org/distorted/external/RubikNetwork.java
@@ -753,9 +753,7 @@ public class RubikNetwork
       HttpURLConnection conn = (HttpURLConnection) connectURL.openConnection();
       conn.setDoInput(true);
       conn.connect();
-      InputStream stream = conn.getInputStream();
-      conn.disconnect();
-      return stream;
+      return conn.getInputStream();
       }
     catch (IOException e)
       {
@@ -773,6 +771,24 @@ public class RubikNetwork
     if(info.mUpdateExtras) info.mExtrasStream = downloadJSON(info.mObjectShortName+"_extras.json");
 
     downloadee.jsonDownloaded();
+
+    try
+      {
+      if( info.mObjectStream!=null ) info.mObjectStream.close();
+      }
+    catch(IOException ioe)
+      {
+      android.util.Log.e("D", "failed to close object input stream");
+      }
+
+    try
+      {
+      if( info.mExtrasStream!=null ) info.mExtrasStream.close();
+      }
+    catch(IOException ioe)
+      {
+      android.util.Log.e("D", "failed to close extras input stream");
+      }
     }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/main/java/org/distorted/objects/RubikObjectList.java b/src/main/java/org/distorted/objects/RubikObjectList.java
index 50f71b47..f6d030d7 100644
--- a/src/main/java/org/distorted/objects/RubikObjectList.java
+++ b/src/main/java/org/distorted/objects/RubikObjectList.java
@@ -121,6 +121,13 @@ public class RubikObjectList
     return type.getNumScramble();
     }
 
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
+  public static void addDownloadedObject(String shortName, boolean icon, boolean object, boolean extras)
+    {
+
+    }
+
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
   public static void setMeshState(int ordinal, int state)
diff --git a/src/main/res/values-de/strings.xml b/src/main/res/values-de/strings.xml
index e04cc6cd..80a955be 100755
--- a/src/main/res/values-de/strings.xml
+++ b/src/main/res/values-de/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">Konfigurieren…</string>
     <string name="saveError">Fehler beim Speichern der Datei</string>
     <string name="networkError">Netzwerkfehler</string>
+    <string name="success">Erfolg</string>
     <string name="view">Sehen</string>
     <string name="level_full">Volles Scramble</string>
 
diff --git a/src/main/res/values-es/strings.xml b/src/main/res/values-es/strings.xml
index 058f5cbf..5280eb20 100755
--- a/src/main/res/values-es/strings.xml
+++ b/src/main/res/values-es/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">Configurando…</string>
     <string name="saveError">Error al guardar el archivo</string>
     <string name="networkError">Error de red</string>
+    <string name="success">Éxito</string>
     <string name="view">Ver</string>
     <string name="level_full">Revuelto Completo</string>
 
diff --git a/src/main/res/values-fr/strings.xml b/src/main/res/values-fr/strings.xml
index 66585783..d54586cd 100755
--- a/src/main/res/values-fr/strings.xml
+++ b/src/main/res/values-fr/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">Configuration…</string>
     <string name="saveError">Échec de l\'enregistrement du fichier</string>
     <string name="networkError">Erreur réseau</string>
+    <string name="success">Succès</string>
     <string name="view">Regarder</string>
     <string name="level_full">Brouillage Complet</string>
 
diff --git a/src/main/res/values-ja/strings.xml b/src/main/res/values-ja/strings.xml
index 94533d4d..0ca3dc3d 100755
--- a/src/main/res/values-ja/strings.xml
+++ b/src/main/res/values-ja/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">構成…</string>
     <string name="saveError">ファイルの保存に失敗しました</string>
     <string name="networkError">ネットワークエラー</string>
+    <string name="success">成功</string>
     <string name="view">見る</string>
     <string name="level_full">フルスクランブル</string>
 
diff --git a/src/main/res/values-ko/strings.xml b/src/main/res/values-ko/strings.xml
index acbbf8d6..5c883322 100755
--- a/src/main/res/values-ko/strings.xml
+++ b/src/main/res/values-ko/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">구성…</string>
     <string name="saveError">파일 저장 실패</string>
     <string name="networkError">네트워크 오류</string>
+    <string name="success">성공</string>
     <string name="view">보다</string>
     <string name="level_full">풀 스크램블</string>
 
diff --git a/src/main/res/values-pl/strings.xml b/src/main/res/values-pl/strings.xml
index b70653fc..5af0c645 100644
--- a/src/main/res/values-pl/strings.xml
+++ b/src/main/res/values-pl/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">Konfigurowanie…</string>
     <string name="saveError">Błąd zapisu pliku</string>
     <string name="networkError">Błąd sieci</string>
+    <string name="success">Sukces</string>
     <string name="view">Zobacz</string>
     <string name="level_full">Pełne Pomieszanie</string>
 
diff --git a/src/main/res/values-ru/strings.xml b/src/main/res/values-ru/strings.xml
index 874e9056..0edd941e 100755
--- a/src/main/res/values-ru/strings.xml
+++ b/src/main/res/values-ru/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">Настройка…</string>
     <string name="saveError">Не удалось сохранить файл</string>
     <string name="networkError">Ошибка сети</string>
+    <string name="success">Успех</string>
     <string name="view">Смотри</string>
     <string name="level_full">Полная Схватка</string>
 
diff --git a/src/main/res/values-zh-rCN/strings.xml b/src/main/res/values-zh-rCN/strings.xml
index 96f19b85..8bc52440 100644
--- a/src/main/res/values-zh-rCN/strings.xml
+++ b/src/main/res/values-zh-rCN/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">配置…</string>
     <string name="saveError">保存文件失败</string>
     <string name="networkError">網絡錯誤</string>
+    <string name="success">成功</string>
     <string name="view">看</string>
     <string name="level_full">级满</string>
 
diff --git a/src/main/res/values-zh-rTW/strings.xml b/src/main/res/values-zh-rTW/strings.xml
index 249b3c16..0f00e9c1 100644
--- a/src/main/res/values-zh-rTW/strings.xml
+++ b/src/main/res/values-zh-rTW/strings.xml
@@ -34,6 +34,7 @@
     <string name="configuring">配置…</string>
     <string name="saveError">保存文件失敗</string>
     <string name="networkError">網絡錯誤</string>
+    <string name="success">成功</string>
     <string name="view">看</string>
     <string name="level_full">級滿</string>
 
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
index 4f5cc4d9..b17a5351 100644
--- a/src/main/res/values/strings.xml
+++ b/src/main/res/values/strings.xml
@@ -35,6 +35,7 @@
     <string name="configuring">Configuring…</string>
     <string name="saveError">Failed to save file</string>
     <string name="networkError">Network Error</string>
+    <string name="success">Success</string>
     <string name="view">View</string>
     <string name="level_full">Full Scramble</string>
 
