Dbrant has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/196974

Change subject: Cache pages on disk instead of ram.
......................................................................

Cache pages on disk instead of ram.

Change-Id: I08cf2aa15895456013145ee5991ee52b0d780d3d
---
A wikipedia/assets/licenses/DiskLruCache
M wikipedia/build.gradle
M wikipedia/res/values/credits.xml
M wikipedia/src/main/java/org/wikipedia/Utils.java
M wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
M wikipedia/src/main/java/org/wikipedia/editing/EditHandler.java
M wikipedia/src/main/java/org/wikipedia/page/Page.java
M wikipedia/src/main/java/org/wikipedia/page/PageCache.java
M wikipedia/src/main/java/org/wikipedia/page/PageProperties.java
M wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
M wikipedia/src/main/java/org/wikipedia/page/Section.java
M wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryActivity.java
M wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryCollection.java
M wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryItem.java
14 files changed, 328 insertions(+), 124 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia 
refs/changes/74/196974/1

diff --git a/wikipedia/assets/licenses/DiskLruCache 
b/wikipedia/assets/licenses/DiskLruCache
new file mode 100644
index 0000000..183fd1f
--- /dev/null
+++ b/wikipedia/assets/licenses/DiskLruCache
@@ -0,0 +1,14 @@
+Copyright 2012 Jake Wharton
+Copyright 2011 The Android Open Source Project
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
\ No newline at end of file
diff --git a/wikipedia/build.gradle b/wikipedia/build.gradle
index 858599c..13face6 100644
--- a/wikipedia/build.gradle
+++ b/wikipedia/build.gradle
@@ -109,6 +109,7 @@
     }
     compile 'de.keyboardsurfer.android.widget:crouton:1.8.5@aar'
     compile 'com.github.chrisbanes.photoview:library:1.2.3'
+    compile 'com.jakewharton:disklrucache:2.0.2'
 }
 
 // The next block is for setting the release signing config from a file 
outside the git repo
diff --git a/wikipedia/res/values/credits.xml b/wikipedia/res/values/credits.xml
index 15b75a5..2e6f0cd 100644
--- a/wikipedia/res/values/credits.xml
+++ b/wikipedia/res/values/credits.xml
@@ -9,6 +9,10 @@
         <!-- 
https://raw.githubusercontent.com/keyboardsurfer/Crouton/master/LICENSE -->
         (<a href="file:///android_asset/licenses/Crouton">license</a>),
 
+        <a href="https://github.com/JakeWharton/DiskLruCache";>DiskLruCache</a>
+        <!-- 
https://github.com/JakeWharton/DiskLruCache/blob/master/LICENSE.txt -->
+        (<a href="file:///android_asset/licenses/DiskLruCache">license</a>),
+
         <a href="https://github.com/kevinsawicki/http-request";>Http-Request</a>
         <!-- 
https://raw.githubusercontent.com/kevinsawicki/http-request/master/LICENSE.md 
-->
         (<a href="file:///android_asset/licenses/Http-Request">license</a>),
diff --git a/wikipedia/src/main/java/org/wikipedia/Utils.java 
b/wikipedia/src/main/java/org/wikipedia/Utils.java
index 6c188d0..b7ab610 100644
--- a/wikipedia/src/main/java/org/wikipedia/Utils.java
+++ b/wikipedia/src/main/java/org/wikipedia/Utils.java
@@ -498,11 +498,14 @@
      * @throws IOException when writing failed
      */
     public static void writeToFile(File file, JSONObject jsonObject) throws 
IOException {
-        OutputStreamWriter writer = new OutputStreamWriter(new 
FileOutputStream(file));
-        try {
+        try (OutputStreamWriter writer = new OutputStreamWriter(new 
FileOutputStream(file))) {
             writer.write(jsonObject.toString());
-        } finally {
-            writer.close();
+        }
+    }
+
+    public static void writeToStream(OutputStream outputStream, String 
contents) throws IOException {
+        try (OutputStreamWriter writer = new OutputStreamWriter(outputStream)) 
{
+            writer.write(contents);
         }
     }
 
@@ -513,16 +516,13 @@
      * @throws JSONException
      */
     public static JSONObject readJSONFile(File f) throws IOException, 
JSONException {
-        BufferedReader reader = new BufferedReader(new InputStreamReader(new 
FileInputStream(f)));
-        try {
+        try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(new FileInputStream(f)))) {
             StringBuilder stringBuilder = new StringBuilder();
             String readStr;
             while ((readStr = reader.readLine()) != null) {
                 stringBuilder.append(readStr);
             }
             return new JSONObject(stringBuilder.toString());
-        } finally {
-            reader.close();
         }
     }
 
@@ -532,16 +532,13 @@
      * @throws IOException
      */
     public static String readFile(final InputStream inputStream) throws 
IOException {
-        BufferedReader reader = new BufferedReader(new 
InputStreamReader(inputStream));
-        try {
+        try (BufferedReader reader = new BufferedReader(new 
InputStreamReader(inputStream))) {
             StringBuilder stringBuilder = new StringBuilder();
             String readStr;
             while ((readStr = reader.readLine()) != null) {
                 stringBuilder.append(readStr).append('\n');
             }
             return stringBuilder.toString();
-        } finally {
-            reader.close();
         }
     }
 
diff --git a/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java 
b/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
index 0fa564e..23435eb 100644
--- a/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
+++ b/wikipedia/src/main/java/org/wikipedia/WikipediaApp.java
@@ -186,7 +186,7 @@
         Api.setConnectionFactory(new OkHttpConnectionFactory(this));
 
         zeroHandler = new WikipediaZeroHandler(this);
-        pageCache = new PageCache();
+        pageCache = new PageCache(this);
 
         new PerformMigrationsTask().execute();
     }
diff --git a/wikipedia/src/main/java/org/wikipedia/editing/EditHandler.java 
b/wikipedia/src/main/java/org/wikipedia/editing/EditHandler.java
index d483c8d..f270cda 100644
--- a/wikipedia/src/main/java/org/wikipedia/editing/EditHandler.java
+++ b/wikipedia/src/main/java/org/wikipedia/editing/EditHandler.java
@@ -86,7 +86,7 @@
                 return;
             }
             int id = messagePayload.optInt("sectionID");
-            Section section = 
Section.findSectionForID(currentPage.getSections(), id);
+            Section section = currentPage.getSections().get(id);
             Intent intent = new Intent(fragment.getActivity(), 
EditSectionActivity.class);
             intent.setAction(EditSectionActivity.ACTION_EDIT_SECTION);
             intent.putExtra(EditSectionActivity.EXTRA_SECTION_ID, 
section.getId());
diff --git a/wikipedia/src/main/java/org/wikipedia/page/Page.java 
b/wikipedia/src/main/java/org/wikipedia/page/Page.java
index 483aead..d7382e2 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/Page.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/Page.java
@@ -107,6 +107,9 @@
             }
             json.putOpt("sections", sectionsJSON);
             json.putOpt("properties", pageProperties.toJSON());
+            if (galleryCollection != null) {
+                json.put("gallery", galleryCollection.toJSON());
+            }
             return json;
         } catch (JSONException e) {
             // This will never happen. Java stinks.
@@ -122,5 +125,8 @@
             sections.add(new Section(sectionsJSON.optJSONObject(i)));
         }
         pageProperties = new PageProperties(json.optJSONObject("properties"));
+        if (json.has("gallery")) {
+            galleryCollection = new 
GalleryCollection(json.optJSONObject("gallery"));
+        }
     }
 }
diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageCache.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageCache.java
index ff5fb2c..75b19de 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/PageCache.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageCache.java
@@ -1,38 +1,182 @@
 package org.wikipedia.page;
 
 import org.wikipedia.PageTitle;
+import org.wikipedia.Utils;
+import org.wikipedia.concurrency.SaneAsyncTask;
 
-import java.util.*;
+import com.jakewharton.disklrucache.DiskLruCache;
+import org.json.JSONObject;
+import android.content.Context;
+import android.os.Environment;
+import android.util.Log;
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 
 /**
- * Implements a cache of Page objects, to be readily retrieved from memory.
- * TODO: make this Parcelable? (or save/restore it from physical storage?)
+ * Implements a cache of Page objects.
  */
 public class PageCache {
+    private static final String TAG = "PageCache";
+    private static final int DISK_CACHE_VERSION = 1;
+    private static final int DISK_CACHE_SIZE = 1024 * 1024 * 64; // 64MB
+    private static final String DISK_CACHE_SUBDIR = "wp_pagecache";
 
-    private static final int MAX_CACHE_ITEMS = 10;
-    private static final float CACHE_LOAD_FACTOR = 0.75f;
+    private DiskLruCache mDiskLruCache;
+    private final Object mDiskCacheLock = new Object();
 
-    private LinkedHashMap<PageTitle, Page> items;
+    public PageCache(Context context) {
+        // Initialize disk cache on background thread
+        File cacheDir = getDiskCacheDir(context, DISK_CACHE_SUBDIR);
+        new InitDiskCacheTask(cacheDir).execute();
+    }
 
-    public PageCache() {
-        items = new LinkedHashMap<PageTitle, Page>(MAX_CACHE_ITEMS, 
CACHE_LOAD_FACTOR, true) {
-            @Override
-            protected boolean removeEldestEntry(Map.Entry eldest) {
-                return size() > MAX_CACHE_ITEMS;
+    private class InitDiskCacheTask extends SaneAsyncTask<Void> {
+        private final File cacheDir;
+
+        public InitDiskCacheTask(File cacheDir) {
+            super(SINGLE_THREAD);
+            this.cacheDir = cacheDir;
+        }
+
+        @Override
+        public Void performTask() throws Throwable {
+            synchronized (mDiskCacheLock) {
+                mDiskLruCache = DiskLruCache.open(cacheDir, 
DISK_CACHE_VERSION, 1, DISK_CACHE_SIZE);
+                mDiskCacheLock.notifyAll(); // Wake any waiting threads
             }
-        };
+            return null;
+        }
+
+        @Override
+        public void onCatch(Throwable caught) {
+            Log.e(TAG, "Caught " + caught.getMessage(), caught);
+            caught.printStackTrace();
+        }
     }
 
-    public boolean has(PageTitle title) {
-        return items.containsKey(title);
+    public interface CachePutListener {
+        void onPutComplete();
+        void onPutError(Throwable e);
     }
 
-    public Page get(PageTitle title) {
-        return items.get(title);
+    public void put(PageTitle title, Page page, final CachePutListener 
listener) {
+        new AddPageToCacheTask(title, page) {
+            @Override
+            public void onFinish(Void v) {
+                listener.onPutComplete();
+            }
+
+            @Override
+            public void onCatch(Throwable caught) {
+                listener.onPutError(caught);
+            }
+        }.execute();
     }
 
-    public void put(PageTitle title, Page page) {
-        items.put(title, page);
+    private class AddPageToCacheTask extends SaneAsyncTask<Void> {
+        private final PageTitle title;
+        private final Page page;
+
+        public AddPageToCacheTask(PageTitle title, Page page) {
+            super(SINGLE_THREAD);
+            this.title = title;
+            this.page = page;
+        }
+
+        @Override
+        public Void performTask() throws Throwable {
+            synchronized (mDiskCacheLock) {
+                if (mDiskLruCache == null) {
+                    return null;
+                }
+                DiskLruCache.Editor editor = null;
+                try {
+                    Log.d(TAG, "Writing to cache: " + title.getDisplayText());
+                    String key = title.getIdentifier();
+                    editor = mDiskLruCache.edit(key);
+                    if (editor == null) {
+                        return null;
+                    }
+                    OutputStream outputStream = new 
BufferedOutputStream(editor.newOutputStream(0));
+                    Utils.writeToStream(outputStream, 
page.toJSON().toString());
+                    mDiskLruCache.flush();
+                    editor.commit();
+                } catch (IOException e) {
+                    if (editor != null) {
+                        editor.abort();
+                    }
+                }
+            }
+            return null;
+        }
+    }
+
+    public interface CacheGetListener {
+        void onGetComplete(Page page);
+        void onGetError(Throwable e);
+    }
+
+    public void get(PageTitle title, final CacheGetListener listener) {
+        new GetPageFromCacheTask(title) {
+            @Override
+            public void onFinish(Page page) {
+                listener.onGetComplete(page);
+            }
+
+            @Override
+            public void onCatch(Throwable caught) {
+                listener.onGetError(caught);
+            }
+        }.execute();
+    }
+
+    private class GetPageFromCacheTask extends SaneAsyncTask<Page> {
+        private final PageTitle title;
+
+        public GetPageFromCacheTask(PageTitle title) {
+            super(SINGLE_THREAD);
+            this.title = title;
+        }
+
+        @Override
+        public Page performTask() throws Throwable {
+            synchronized (mDiskCacheLock) {
+                if (mDiskLruCache == null) {
+                    return null;
+                }
+                String key = title.getIdentifier();
+                DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key);
+                if (snapshot == null) {
+                    return null;
+                }
+                try {
+                    Log.d(TAG, "Reading from cache: " + 
title.getDisplayText());
+                    InputStream inputStream = new 
BufferedInputStream(snapshot.getInputStream(0));
+                    String jsonStr = Utils.readFile(inputStream);
+                    return new Page(new JSONObject(jsonStr));
+                } finally {
+                    snapshot.close();
+                }
+            }
+        }
+    }
+
+    // Creates a unique subdirectory of the designated app cache directory. 
Tries to use external
+    // storage, but if not mounted, falls back on internal storage.
+    public static File getDiskCacheDir(Context context, String uniqueName) {
+        // Check if media is mounted or storage is built-in, if so, try and 
use external cache dir
+        // otherwise use internal cache dir.
+        final String cachePath;
+        if 
((Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
+             Environment.isExternalStorageRemovable()) && 
context.getExternalCacheDir() != null) {
+            cachePath = context.getExternalCacheDir().getPath();
+        } else {
+            cachePath = context.getCacheDir().getPath();
+        }
+        return new File(cachePath + File.separator + uniqueName);
     }
 }
diff --git a/wikipedia/src/main/java/org/wikipedia/page/PageProperties.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageProperties.java
index 09003b7..2360b4c 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/PageProperties.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageProperties.java
@@ -213,7 +213,7 @@
             }
             if (leadImageName != null) {
                 JSONObject imageObject = new JSONObject();
-                imageObject.put("file", leadImageUrl);
+                imageObject.put("file", leadImageName);
                 json.put("image", imageObject);
             }
         } catch (JSONException e) {
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java 
b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
index ed2ef10..e57c225 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/PageViewFragmentInternal.java
@@ -105,6 +105,8 @@
      */
     private boolean saveOnComplete = false;
 
+    private boolean cacheOnComplete = true;
+
     private PageViewFragment parentFragment;
 
     private PageTitle title;
@@ -424,12 +426,35 @@
         }
 
         //is this page in cache??
-        if (app.getPageCache().has(titleOriginal)) {
-            Log.d(TAG, "Using page from cache: " + 
titleOriginal.getDisplayText());
-            page = app.getPageCache().get(titleOriginal);
-            title = page.getTitle();
-            state = STATE_COMPLETE_FETCH;
-        }
+        getActivity().updateProgressBar(true, true, 0);
+        app.getPageCache().get(titleOriginal, new PageCache.CacheGetListener() 
{
+            @Override
+            public void onGetComplete(Page page) {
+                if (page != null) {
+                    Log.d(TAG, "Using page from cache: " + 
titleOriginal.getDisplayText());
+                    PageViewFragmentInternal.this.page = page;
+                    title = page.getTitle();
+                    state = STATE_COMPLETE_FETCH;
+                    cacheOnComplete = false;
+                } else {
+                    // fetch the page from the network...
+                    state = STATE_NO_FETCH;
+                    cacheOnComplete = true;
+                }
+                setState(state);
+                performActionForState(state);
+            }
+
+            @Override
+            public void onGetError(Throwable e) {
+                Log.e(TAG, "Failed to get page from cache: " + e);
+                e.printStackTrace();
+                state = STATE_NO_FETCH;
+                cacheOnComplete = true;
+                setState(state);
+                performActionForState(state);
+            }
+        });
 
         if (tocHandler == null) {
             tocHandler = new ToCHandler(getActivity(),
@@ -438,9 +463,6 @@
                     title.getSite(),
                     isFirstPage());
         }
-
-        setState(state);
-        performActionForState(state);
     }
 
     private boolean isFirstPage() {
@@ -630,10 +652,23 @@
             tocHandler.setupToC(page);
 
             //add the page to cache!
-            app.getPageCache().put(titleOriginal, page);
-            if (!titleOriginal.equals(title)) {
-                app.getPageCache().put(title, page);
+            if (cacheOnComplete) {
+                app.getPageCache().put(titleOriginal, page, new 
PageCache.CachePutListener() {
+                    @Override
+                    public void onPutComplete() {
+                    }
+
+                    @Override
+                    public void onPutError(Throwable e) {
+                        Log.e(TAG, "Failed to add page to cache: " + e);
+                        e.printStackTrace();
+                    }
+                });
+                //if (!titleOriginal.equals(title)) {
+                //    app.getPageCache().put(title, page);
+                //}
             }
+
         }
     }
 
@@ -780,7 +815,7 @@
         Intent galleryIntent = new Intent();
         galleryIntent.setClass(getActivity(), GalleryActivity.class);
         galleryIntent.putExtra(GalleryActivity.EXTRA_IMAGETITLE, imageTitle);
-        galleryIntent.putExtra(GalleryActivity.EXTRA_PAGETITLE, title);
+        galleryIntent.putExtra(GalleryActivity.EXTRA_PAGETITLE, titleOriginal);
         getActivity().startActivityForResult(galleryIntent, 
PageActivity.ACTIVITY_REQUEST_GALLERY);
     }
 
@@ -1101,6 +1136,7 @@
 
     public void refreshPage(boolean saveOnComplete) {
         this.saveOnComplete = saveOnComplete;
+        cacheOnComplete = true;
         if (saveOnComplete) {
             Toast.makeText(getActivity(), R.string.toast_refresh_saved_page, 
Toast.LENGTH_LONG).show();
         }
diff --git a/wikipedia/src/main/java/org/wikipedia/page/Section.java 
b/wikipedia/src/main/java/org/wikipedia/page/Section.java
index cfadfab..db06a1a 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/Section.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/Section.java
@@ -1,17 +1,12 @@
 package org.wikipedia.page;
 
-import android.os.Parcel;
-import android.os.Parcelable;
 import org.json.JSONException;
 import org.json.JSONObject;
-import org.wikipedia.Utils;
-
-import java.util.List;
 
 /**
  * Represents a particular section of an article.
  */
-public class Section implements Parcelable {
+public class Section {
 
     private final JSONObject data;
 
@@ -33,35 +28,6 @@
             // This, also, will never happen. Very similar to Java being sane, 
some say.
             throw new RuntimeException(e);
         }
-    }
-
-    // This won't actually throw
-    private Section(Parcel in) throws JSONException {
-        this(new JSONObject(in.readString()));
-    }
-
-    @Override
-    public boolean equals(Object o) {
-        if (!(o instanceof Section)) {
-            return false;
-        }
-
-        Section other = (Section) o;
-        return getId() == other.getId()
-                && getLevel() == other.getLevel()
-                && Utils.compareStrings(getHeading(), other.getHeading())
-                && Utils.compareStrings(getAnchor(), other.getAnchor())
-                && Utils.compareStrings(getContent(), other.getContent());
-
-    }
-
-    @Override
-    public int hashCode() {
-        int result = getId();
-        result = 31 * result + getHeading().hashCode();
-        result = 31 * result + getAnchor().hashCode();
-        result = 31 * result + getContent().hashCode();
-        return result;
     }
 
     @Override
@@ -99,33 +65,4 @@
         return data;
     }
 
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel parcel, int flags) {
-        parcel.writeString(toJSON().toString());
-    }
-
-    public static final Parcelable.Creator<Section> CREATOR
-            = new Parcelable.Creator<Section>() {
-        public Section createFromParcel(Parcel in) {
-            try {
-                return new Section(in);
-            } catch (JSONException e) {
-                // This won't happen
-                throw new RuntimeException(e);
-            }
-        }
-
-        public Section[] newArray(int size) {
-            return new Section[size];
-        }
-    };
-
-    public static Section findSectionForID(List<Section> sections, int id) {
-        return sections.get(id);
-    }
 }
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryActivity.java 
b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryActivity.java
index f4fd8c4..09b7d75 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryActivity.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryActivity.java
@@ -12,11 +12,13 @@
 import org.wikipedia.page.LinkMovementMethodExt;
 import org.wikipedia.page.Page;
 import org.wikipedia.page.PageActivity;
+import org.wikipedia.page.PageCache;
 
 import android.content.Intent;
 import android.net.Uri;
 import android.os.Build;
 import android.os.Bundle;
+import android.os.Parcelable;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.FragmentPagerAdapter;
 import android.support.v4.app.FragmentTransaction;
@@ -41,6 +43,7 @@
 import java.util.Map;
 
 public class GalleryActivity extends ThemedActionBarActivity {
+    private static final String TAG = "GalleryActivity";
     public static final int ACTIVITY_RESULT_FILEPAGE_SELECT = 1;
 
     public static final String EXTRA_PAGETITLE = "pageTitle";
@@ -49,6 +52,7 @@
     private WikipediaApp app;
     private PageTitle pageTitle;
     private Page page;
+    private boolean cacheOnLoad;
 
     private GalleryFunnel funnel;
     public GalleryFunnel getFunnel() {
@@ -142,11 +146,6 @@
         pageTitle = getIntent().getParcelableExtra(EXTRA_PAGETITLE);
         initialImageTitle = getIntent().getParcelableExtra(EXTRA_IMAGETITLE);
 
-        // find our Page in the page cache...
-        if (app.getPageCache().has(pageTitle)) {
-            page = app.getPageCache().get(pageTitle);
-        }
-
         galleryCache = new HashMap<>();
         galleryPager = (ViewPager) findViewById(R.id.gallery_item_pager);
         galleryAdapter = new GalleryItemAdapter(this);
@@ -210,13 +209,30 @@
 
         updateProgressBar(false, true, 0);
 
-        // if our page already has a prepopulated gallery collection, then use 
it!
-        if (page != null && page.getGalleryCollection() != null) {
-            applyGalleryCollection(page.getGalleryCollection());
-        } else {
-            // otherwise, fetch it!
-            fetchGalleryCollection();
-        }
+        // find our Page in the page cache...
+        app.getPageCache().get(pageTitle, new PageCache.CacheGetListener() {
+            @Override
+            public void onGetComplete(Page page) {
+                GalleryActivity.this.page = page;
+                if (page != null && page.getGalleryCollection() != null) {
+                    applyGalleryCollection(page.getGalleryCollection());
+                    cacheOnLoad = false;
+                } else {
+                    // fetch the gallery from the network...
+                    fetchGalleryCollection();
+                    cacheOnLoad = true;
+                }
+            }
+
+            @Override
+            public void onGetError(Throwable e) {
+                Log.e(TAG, "Failed to get page from cache: " + e);
+                e.printStackTrace();
+                fetchGalleryCollection();
+                cacheOnLoad = true;
+            }
+        });
+
     }
 
     @Override
@@ -346,7 +362,7 @@
         Intent intent = new Intent();
         intent.setClass(GalleryActivity.this, PageActivity.class);
         intent.setAction(PageActivity.ACTION_PAGE_FOR_TITLE);
-        intent.putExtra(PageActivity.EXTRA_PAGETITLE, resultTitle);
+        intent.putExtra(PageActivity.EXTRA_PAGETITLE, (Parcelable) 
resultTitle);
         intent.putExtra(PageActivity.EXTRA_HISTORYENTRY, historyEntry);
         setResult(ACTIVITY_RESULT_FILEPAGE_SELECT, intent);
         finish();
@@ -365,8 +381,19 @@
             public void onGalleryResult(GalleryCollection result) {
                 updateProgressBar(false, true, 0);
                 // save it to our current page, for later use
-                if (page != null) {
+                if (cacheOnLoad && page != null) {
                     page.setGalleryCollection(result);
+                    app.getPageCache().put(pageTitle, page, new 
PageCache.CachePutListener() {
+                        @Override
+                        public void onPutComplete() {
+                        }
+
+                        @Override
+                        public void onPutError(Throwable e) {
+                            Log.e(TAG, "Failed to add page to cache: " + e);
+                            e.printStackTrace();
+                        }
+                    });
                 }
                 applyGalleryCollection(result);
             }
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryCollection.java 
b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryCollection.java
index 089c100..b1a8a15 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryCollection.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryCollection.java
@@ -1,6 +1,9 @@
 package org.wikipedia.page.gallery;
 
 import org.wikipedia.PageTitle;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -14,6 +17,36 @@
         return itemList;
     }
 
+    public JSONObject toJSON() {
+        JSONObject json = new JSONObject();
+        try {
+            JSONArray itemsJSON = new JSONArray();
+            for (GalleryItem item : itemList) {
+                JSONObject itemJSON = item.toJSON();
+                if (itemJSON != null) {
+                    itemsJSON.put(itemJSON);
+                }
+            }
+            json.put("items", itemsJSON);
+            return json;
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public GalleryCollection(JSONObject json) {
+        itemList = new ArrayList<>();
+        try {
+            JSONArray itemsJSON = json.getJSONArray("items");
+            for (int i = 0; i < itemsJSON.length(); i++) {
+                JSONObject itemJSON = itemsJSON.getJSONObject(i);
+                itemList.add(new GalleryItem(itemJSON));
+            }
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
     public GalleryCollection(Map<PageTitle, GalleryItem> galleryMap) {
         itemList = new ArrayList<>();
         Iterator iterator = galleryMap.keySet().iterator();
diff --git 
a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryItem.java 
b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryItem.java
index 03132c0..41f5e09 100644
--- a/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryItem.java
+++ b/wikipedia/src/main/java/org/wikipedia/page/gallery/GalleryItem.java
@@ -9,6 +9,9 @@
 import java.util.Map;
 
 public class GalleryItem {
+    private final JSONObject json;
+    public JSONObject toJSON() { return json; }
+
     private final String name;
     public String getName() { return name; }
 
@@ -61,6 +64,7 @@
     }
 
     public GalleryItem(String name) {
+        this.json = null;
         this.name = name;
         this.url = null;
         this.mimeType = "*/*";
@@ -71,6 +75,7 @@
     }
 
     public GalleryItem(JSONObject json) throws JSONException {
+        this.json = json;
         this.name = json.getString("title");
         JSONObject objinfo;
         if (json.has("imageinfo")) {

-- 
To view, visit https://gerrit.wikimedia.org/r/196974
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I08cf2aa15895456013145ee5991ee52b0d780d3d
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Dbrant <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to