Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/AppIndexingUtil.java

Issue 2820453002: Add a cache for recently viewed webpages. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser; 5 package org.chromium.chrome.browser;
6 6
7 import android.os.SystemClock;
8 import android.util.LruCache;
7 import android.webkit.URLUtil; 9 import android.webkit.URLUtil;
8 10
9 import org.chromium.base.SysUtils; 11 import org.chromium.base.SysUtils;
12 import org.chromium.base.VisibleForTesting;
10 import org.chromium.blink.mojom.document_metadata.CopylessPaste; 13 import org.chromium.blink.mojom.document_metadata.CopylessPaste;
11 import org.chromium.blink.mojom.document_metadata.WebPage; 14 import org.chromium.blink.mojom.document_metadata.WebPage;
12 import org.chromium.chrome.browser.historyreport.AppIndexingReporter; 15 import org.chromium.chrome.browser.historyreport.AppIndexingReporter;
13 import org.chromium.chrome.browser.tab.Tab; 16 import org.chromium.chrome.browser.tab.Tab;
14 import org.chromium.content_public.browser.RenderFrameHost; 17 import org.chromium.content_public.browser.RenderFrameHost;
15 import org.chromium.content_public.browser.WebContents; 18 import org.chromium.content_public.browser.WebContents;
16 import org.chromium.services.service_manager.InterfaceProvider; 19 import org.chromium.services.service_manager.InterfaceProvider;
17 20
18 /** 21 /**
19 * This is the top-level CopylessPaste metadata extraction for AppIndexing. 22 * This is the top-level CopylessPaste metadata extraction for AppIndexing.
20 */ 23 */
21 public class AppIndexingUtil { 24 public class AppIndexingUtil {
22 public static void extractCopylessPasteMetadata(final Tab tab) { 25 private static final int CACHE_SIZE = 100;
23 String url = tab.getUrl(); 26 private static final int CACHE_VISIT_CUTOFF_MS = 60 * 60 * 1000; // 1 hour
27 // Cache of recently seen urls. If a url is among the CACHE_SIZE most recent pages visited, and
28 // the visit was in the last CACHE_VISIT_CUTOFF_MS milliseconds, then we don 't parse the page,
wychen 2017/04/13 07:05:00 and the *parsing* was in the last ... Our expirat
dproctor 2017/04/13 17:23:09 Thanks, yeah, the comparison is made based on the
29 // and instead just report the view (not the content) to App Indexing.
30 private final LruCache<String, CacheEntry> mPageCache;
31
32 public AppIndexingUtil() {
33 this(CACHE_SIZE);
34 }
35
36 private AppIndexingUtil(int cacheSize) {
37 mPageCache = new LruCache<String, CacheEntry>(cacheSize);
38 }
39
40 public void extractCopylessPasteMetadata(final Tab tab) {
41 final String url = tab.getUrl();
24 boolean isHttpOrHttps = URLUtil.isHttpsUrl(url) || URLUtil.isHttpUrl(url ); 42 boolean isHttpOrHttps = URLUtil.isHttpsUrl(url) || URLUtil.isHttpUrl(url );
25 if (SysUtils.isLowEndDevice() || tab.isIncognito() 43 if (!isEnabledForDevice() || tab.isIncognito() || !isHttpOrHttps) {
26 || !ChromeFeatureList.isEnabled(ChromeFeatureList.COPYLESS_PASTE )
27 || !isHttpOrHttps) {
28 return; 44 return;
29 } 45 }
30 46
47 // There are three conditions that can occur with respect to the cache.
wychen 2017/04/13 07:05:00 We might want to add UMA to track the distribution
dproctor 2017/04/13 17:34:58 How about we add this in a follow-up cl?
wychen 2017/04/13 18:04:45 No problem.
48 // 1. Cache hit, and an entity was found previously. Report only the pag e view to App
49 // Indexing.
50 // 2. Cache hit, but no entity was found. Ignore.
51 // 3. Cache miss, we need to parse the page.
52 if (wasPageVisitedRecently(url)) {
53 if (lastPageVisitContainedEntity(url)) {
54 // Condition 1
55 getAppIndexingReporter().reportWebPageView(url, tab.getTitle());
56 }
57 // Condition 2
58 } else {
59 // Condition 3
60 CopylessPaste copylessPaste = getCopylessPasteInterface(tab);
61 if (copylessPaste == null) {
62 return;
63 }
64 copylessPaste.getEntities(new CopylessPaste.GetEntitiesResponse() {
65 @Override
66 public void call(WebPage webpage) {
67 putCacheEntry(url, webpage != null);
68 if (webpage == null) return;
69 getAppIndexingReporter().reportWebPage(webpage);
70 }
71 });
72 }
73 }
74
75 private boolean wasPageVisitedRecently(String url) {
76 if (url == null) {
77 return false;
78 }
79 CacheEntry entry = mPageCache.get(url);
80 if (entry == null || getElapsedTime() - entry.lastSeenTimeMs > CACHE_VIS IT_CUTOFF_MS) {
81 return false;
82 }
83 return true;
84 }
85
86 // Returns true if the page is in the cache and it contained an entity the l ast time it was
87 // visited.
wychen 2017/04/13 07:05:00 it was *parsed*
dproctor 2017/04/13 17:23:09 Done.
88 private boolean lastPageVisitContainedEntity(String url) {
89 if (url == null) {
90 return false;
91 }
92 CacheEntry entry = mPageCache.get(url);
93 if (entry == null || !entry.containedEntity) {
94 return false;
95 }
96 return true;
97 }
98
99 private void putCacheEntry(String url, boolean containedEntity) {
100 CacheEntry entry = new CacheEntry();
101 entry.lastSeenTimeMs = getElapsedTime();
102 entry.containedEntity = containedEntity;
103 mPageCache.put(url, entry);
104 }
105
106 @VisibleForTesting
107 AppIndexingReporter getAppIndexingReporter() {
108 return AppIndexingReporter.getInstance();
109 }
110
111 @VisibleForTesting
112 CopylessPaste getCopylessPasteInterface(Tab tab) {
31 WebContents webContents = tab.getWebContents(); 113 WebContents webContents = tab.getWebContents();
32 if (webContents == null) return; 114 if (webContents == null) return null;
33 115
34 RenderFrameHost mainFrame = webContents.getMainFrame(); 116 RenderFrameHost mainFrame = webContents.getMainFrame();
35 if (mainFrame == null) return; 117 if (mainFrame == null) return null;
36 118
37 InterfaceProvider interfaces = mainFrame.getRemoteInterfaces(); 119 InterfaceProvider interfaces = mainFrame.getRemoteInterfaces();
38 if (interfaces == null) return; 120 if (interfaces == null) return null;
39 121
40 CopylessPaste copylesspaste = interfaces.getInterface(CopylessPaste.MANA GER); 122 return interfaces.getInterface(CopylessPaste.MANAGER);
41 copylesspaste.getEntities(new CopylessPaste.GetEntitiesResponse() { 123 }
42 @Override 124
43 public void call(WebPage webpage) { 125 @VisibleForTesting
44 if (webpage == null) return; 126 long getElapsedTime() {
45 AppIndexingReporter.getInstance().reportWebPage(webpage); 127 return SystemClock.elapsedRealtime();
46 } 128 }
47 }); 129
130 boolean isEnabledForDevice() {
131 return !SysUtils.isLowEndDevice()
132 && ChromeFeatureList.isEnabled(ChromeFeatureList.COPYLESS_PASTE) ;
133 }
134
135 private static class CacheEntry {
136 public long lastSeenTimeMs;
137 public boolean containedEntity;
48 } 138 }
49 } 139 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698