Mholloway has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/380528 )
Change subject: Immediately fetch, cache page content when opening in
background tab
......................................................................
Immediately fetch, cache page content when opening in background tab
Adds a new PageCacher class, similar to but distinct from the
SavedPageSyncService (which does more). Exposes a static loadIntoCache
method that can be used to grab and cache all content for a page.
TODO (in a follow-up): Immediately update the tab list icons.
Bug: T168310
Change-Id: I4682f03d6993244442ba63de402d417c51ba1f70
---
M app/src/main/java/org/wikipedia/page/PageBackStackItem.java
A app/src/main/java/org/wikipedia/page/PageCacher.java
M app/src/main/java/org/wikipedia/page/PageFragment.java
3 files changed, 160 insertions(+), 7 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/28/380528/1
diff --git a/app/src/main/java/org/wikipedia/page/PageBackStackItem.java
b/app/src/main/java/org/wikipedia/page/PageBackStackItem.java
index 80ffe3c..270cba9 100644
--- a/app/src/main/java/org/wikipedia/page/PageBackStackItem.java
+++ b/app/src/main/java/org/wikipedia/page/PageBackStackItem.java
@@ -5,21 +5,35 @@
import org.wikipedia.history.HistoryEntry;
import org.wikipedia.model.BaseModel;
+import static org.wikipedia.page.PageCacher.loadIntoCache;
+
public class PageBackStackItem extends BaseModel {
- private final PageTitle title;
- @NonNull private final HistoryEntry historyEntry;
+ @NonNull private PageTitle title;
+ @NonNull private HistoryEntry historyEntry;
+
private int scrollY;
public PageBackStackItem(PageTitle title, @NonNull HistoryEntry
historyEntry) {
- this.title = title;
- this.historyEntry = historyEntry;
+ this(title, historyEntry, false);
}
+ public PageBackStackItem(@NonNull PageTitle title, @NonNull HistoryEntry
entry,
+ boolean loadPageContentOnCreate) {
+ this.title = title;
+ this.historyEntry = entry;
+
+ if (loadPageContentOnCreate) {
+ loadIntoCache(title);
+ }
+ }
+
+ @NonNull
public PageTitle getTitle() {
return title;
}
- @NonNull public HistoryEntry getHistoryEntry() {
+ @NonNull
+ public HistoryEntry getHistoryEntry() {
return historyEntry;
}
diff --git a/app/src/main/java/org/wikipedia/page/PageCacher.java
b/app/src/main/java/org/wikipedia/page/PageCacher.java
new file mode 100644
index 0000000..be5a75f
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/page/PageCacher.java
@@ -0,0 +1,138 @@
+package org.wikipedia.page;
+
+import android.support.annotation.NonNull;
+
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.dataclient.WikiSite;
+import org.wikipedia.dataclient.okhttp.OkHttpConnectionFactory;
+import org.wikipedia.dataclient.page.PageClient;
+import org.wikipedia.dataclient.page.PageClientFactory;
+import org.wikipedia.dataclient.page.PageLead;
+import org.wikipedia.dataclient.page.PageRemaining;
+import org.wikipedia.html.ImageTagParser;
+import org.wikipedia.html.PixelDensityDescriptorParser;
+import org.wikipedia.savedpages.PageImageUrlParser;
+import org.wikipedia.util.log.L;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+import okhttp3.OkHttpClient;
+import okhttp3.Request;
+import retrofit2.Call;
+import retrofit2.Callback;
+import retrofit2.Response;
+
+import static org.wikipedia.settings.Prefs.isImageDownloadEnabled;
+import static org.wikipedia.util.DimenUtil.calculateLeadImageWidth;
+import static org.wikipedia.util.UriUtil.resolveProtocolRelativeUrl;
+
+public final class PageCacher {
+
+ public static void loadIntoCache(@NonNull PageTitle title) {
+ L.d("Loading page into cache: " + title.getPrefixedText());
+ WikipediaApp app = WikipediaApp.getInstance();
+ PageImageUrlParser parser = new PageImageUrlParser(new
ImageTagParser(),
+ new PixelDensityDescriptorParser());
+ PageClient client = PageClientFactory.create(title.getWikiSite(),
title.namespace());
+ app.getSessionFunnel().leadSectionFetchStart();
+ leadReq(client, title).enqueue(new LeadCallback(title.getWikiSite(),
parser));
+ app.getSessionFunnel().restSectionsFetchStart();
+ remainingReq(client, title).enqueue(new
RemainingCallback(title.getWikiSite(), parser));
+ }
+
+ @NonNull
+ private static Call<PageLead> leadReq(@NonNull PageClient client, @NonNull
PageTitle title) {
+ return client.lead(null, PageClient.CacheOption.CACHE,
title.getPrefixedText(),
+ calculateLeadImageWidth(), !isImageDownloadEnabled());
+ }
+
+ @NonNull
+ private static Call<PageRemaining> remainingReq(@NonNull PageClient client,
+ @NonNull PageTitle title) {
+ return client.sections(null, PageClient.CacheOption.CACHE,
title.getPrefixedText(),
+ !isImageDownloadEnabled());
+ }
+
+ private static void fetchImages(@NonNull final WikiSite wiki,
+ @NonNull final Iterable<String> urls) {
+ OkHttpClient client = OkHttpConnectionFactory.getClient();
+ for (String url : urls) {
+ url = resolveProtocolRelativeUrl(wiki, url);
+ Request request = new Request.Builder().url(url).build();
+ client.newCall(request).enqueue(new ImageCallback());
+ }
+ }
+
+ private static final class LeadCallback implements Callback<PageLead> {
+ @NonNull private PageImageUrlParser parser;
+ @NonNull private WikiSite wiki;
+
+ private LeadCallback(@NonNull WikiSite wiki, @NonNull
PageImageUrlParser parser) {
+ this.parser = parser;
+ this.wiki = wiki;
+ }
+
+ @Override
+ public void onResponse(@NonNull Call<PageLead> call, @NonNull
Response<PageLead> response) {
+
WikipediaApp.getInstance().getSessionFunnel().leadSectionFetchEnd();
+ if (response.body() != null) {
+ // noinspection ConstantConditions
+ Set<String> imageUrls = new
HashSet<>(parser.parse(response.body()));
+ fetchImages(wiki, imageUrls);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call<PageLead> call, @NonNull Throwable
t) {
+ L.e(t);
+ }
+ }
+
+ private static final class RemainingCallback implements
Callback<PageRemaining> {
+ @NonNull private PageImageUrlParser parser;
+ @NonNull private WikiSite wiki;
+
+ private RemainingCallback(@NonNull WikiSite wiki, @NonNull
PageImageUrlParser parser) {
+ this.parser = parser;
+ this.wiki = wiki;
+ }
+
+ @Override
+ public void onResponse(@NonNull Call<PageRemaining> call,
+ @NonNull Response<PageRemaining> response) {
+
WikipediaApp.getInstance().getSessionFunnel().restSectionsFetchEnd();
+ if (response.body() != null) {
+ // noinspection ConstantConditions
+ Set<String> imageUrls = new
HashSet<>(parser.parse(response.body()));
+ fetchImages(wiki, imageUrls);
+ }
+ }
+
+ @Override
+ public void onFailure(@NonNull Call<PageRemaining> call, @NonNull
Throwable t) {
+ L.e(t);
+ }
+ }
+
+ private static class ImageCallback implements okhttp3.Callback {
+ @Override
+ public void onFailure(@NonNull okhttp3.Call call, @NonNull IOException
e) {
+ L.e(e);
+ }
+
+ @Override
+ public void onResponse(@NonNull okhttp3.Call call, @NonNull
okhttp3.Response response)
+ throws IOException {
+ // Note: raw non-Retrofit usage of OkHttp Requests requires that
the Response body is
+ // read for the cache to be written.
+ if (response.body() != null) {
+ // noinspection ConstantConditions
+ response.body().close();
+ }
+ }
+ }
+
+ private PageCacher() { }
+}
diff --git a/app/src/main/java/org/wikipedia/page/PageFragment.java
b/app/src/main/java/org/wikipedia/page/PageFragment.java
index d86f641..4a5d908 100755
--- a/app/src/main/java/org/wikipedia/page/PageFragment.java
+++ b/app/src/main/java/org/wikipedia/page/PageFragment.java
@@ -1053,8 +1053,9 @@
if (shouldCreateNewTab()) {
// create a new tab
Tab tab = new Tab();
+ boolean isForeground = position == getForegroundTabPosition();
// if the requested position is at the top, then make its
backstack current
- if (position == getForegroundTabPosition()) {
+ if (isForeground) {
pageFragmentLoadState.setBackStack(tab.getBackStack());
}
// put this tab in the requested position
@@ -1062,7 +1063,7 @@
trimTabCount();
tabsProvider.invalidate();
// add the requested page to its backstack
- tab.getBackStack().add(new PageBackStackItem(title, entry));
+ tab.getBackStack().add(new PageBackStackItem(title, entry,
!isForeground));
getActivity().supportInvalidateOptionsMenu();
} else {
getTopMostTab().getBackStack().add(new PageBackStackItem(title,
entry));
--
To view, visit https://gerrit.wikimedia.org/r/380528
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I4682f03d6993244442ba63de402d417c51ba1f70
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Mholloway <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits