blob: 99909b359b96f5033834805e8f6307d29a51b561 [file] [log] [blame]
Michael Kolb14612442011-06-24 13:06:29 -07001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Bijan Amirzada41242f22014-03-21 12:12:18 -070016package com.android.browser;
Michael Kolb14612442011-06-24 13:06:29 -070017
18import android.content.Context;
19import android.os.Handler;
20import android.os.Looper;
Michael Kolb14612442011-06-24 13:06:29 -070021import android.util.Log;
Bijan Amirzada9b1e9882014-02-26 17:15:46 -080022import org.codeaurora.swe.WebView;
Michael Kolb14612442011-06-24 13:06:29 -070023
Michael Kolb14612442011-06-24 13:06:29 -070024import java.util.Map;
25
26/**
27 * Singleton class for handling preload requests.
28 */
29public class Preloader {
30
31 private final static String LOGTAG = "browser.preloader";
Bijan Amirzada41242f22014-03-21 12:12:18 -070032 private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
Michael Kolb14612442011-06-24 13:06:29 -070033
34 private static final int PRERENDER_TIMEOUT_MILLIS = 30 * 1000; // 30s
35
36 private static Preloader sInstance;
37
38 private final Context mContext;
39 private final Handler mHandler;
40 private final BrowserWebViewFactory mFactory;
Narayan Kamathf27b7102011-07-22 13:11:53 +010041 private volatile PreloaderSession mSession;
Michael Kolb14612442011-06-24 13:06:29 -070042
43 public static void initialize(Context context) {
44 sInstance = new Preloader(context);
45 }
46
47 public static Preloader getInstance() {
48 return sInstance;
49 }
50
51 private Preloader(Context context) {
Ben Murdoch914c5592011-08-01 13:58:47 +010052 mContext = context.getApplicationContext();
Michael Kolb14612442011-06-24 13:06:29 -070053 mHandler = new Handler(Looper.getMainLooper());
Narayan Kamathf27b7102011-07-22 13:11:53 +010054 mSession = null;
Michael Kolb14612442011-06-24 13:06:29 -070055 mFactory = new BrowserWebViewFactory(context);
56
Axesh R. Ajmera579c70c2014-04-17 13:24:56 -070057 // Creating dummy Webview for browser to force loading of library;
58 // This will thereby prevent any singleton calls invoked directly
59 // even without the webview creation
60 (mFactory.instantiateWebView(null, android.R.attr.webViewStyle, false)).destroy();
Michael Kolb14612442011-06-24 13:06:29 -070061 }
62
63 private PreloaderSession getSession(String id) {
Narayan Kamathf27b7102011-07-22 13:11:53 +010064 if (mSession == null) {
Michael Kolb14612442011-06-24 13:06:29 -070065 if (LOGD_ENABLED) Log.d(LOGTAG, "Create new preload session " + id);
Narayan Kamathf27b7102011-07-22 13:11:53 +010066 mSession = new PreloaderSession(id);
67 WebViewTimersControl.getInstance().onPrerenderStart(
68 mSession.getWebView());
69 return mSession;
70 } else if (mSession.mId.equals(id)) {
71 if (LOGD_ENABLED) Log.d(LOGTAG, "Returning existing preload session " + id);
72 return mSession;
Michael Kolb14612442011-06-24 13:06:29 -070073 }
Narayan Kamathf27b7102011-07-22 13:11:53 +010074
75 if (LOGD_ENABLED) Log.d(LOGTAG, "Existing session in progress : " + mSession.mId +
76 " returning null.");
77 return null;
Michael Kolb14612442011-06-24 13:06:29 -070078 }
79
80 private PreloaderSession takeSession(String id) {
Narayan Kamathf27b7102011-07-22 13:11:53 +010081 PreloaderSession s = null;
82 if (mSession != null && mSession.mId.equals(id)) {
83 s = mSession;
84 mSession = null;
85 }
86
Michael Kolb14612442011-06-24 13:06:29 -070087 if (s != null) {
88 s.cancelTimeout();
89 }
Narayan Kamathf27b7102011-07-22 13:11:53 +010090
Michael Kolb14612442011-06-24 13:06:29 -070091 return s;
92 }
93
Mathew Inwood29721c22011-06-29 17:55:24 +010094 public void handlePreloadRequest(String id, String url, Map<String, String> headers,
95 String searchBoxQuery) {
Michael Kolb14612442011-06-24 13:06:29 -070096 PreloaderSession s = getSession(id);
Narayan Kamathf27b7102011-07-22 13:11:53 +010097 if (s == null) {
98 if (LOGD_ENABLED) Log.d(LOGTAG, "Discarding preload request, existing"
99 + " session in progress");
100 return;
101 }
102
Michael Kolb14612442011-06-24 13:06:29 -0700103 s.touch(); // reset timer
Mathew Inwood29721c22011-06-29 17:55:24 +0100104 PreloadedTabControl tab = s.getTabControl();
105 if (searchBoxQuery != null) {
106 tab.loadUrlIfChanged(url, headers);
107 tab.setQuery(searchBoxQuery);
108 } else {
109 tab.loadUrl(url, headers);
110 }
Michael Kolb14612442011-06-24 13:06:29 -0700111 }
112
Mathew Inwooddffa72f2011-08-10 12:37:43 +0100113 public void cancelSearchBoxPreload(String id) {
114 PreloaderSession s = getSession(id);
115 if (s != null) {
116 s.touch(); // reset timer
117 PreloadedTabControl tab = s.getTabControl();
118 tab.searchBoxCancel();
119 }
120 }
121
Michael Kolb14612442011-06-24 13:06:29 -0700122 public void discardPreload(String id) {
123 PreloaderSession s = takeSession(id);
124 if (s != null) {
125 if (LOGD_ENABLED) Log.d(LOGTAG, "Discard preload session " + id);
Mathew Inwoodcf9120e2011-08-02 17:36:07 +0100126 WebViewTimersControl.getInstance().onPrerenderDone(s == null ? null : s.getWebView());
Mathew Inwood29721c22011-06-29 17:55:24 +0100127 PreloadedTabControl t = s.getTabControl();
Michael Kolb14612442011-06-24 13:06:29 -0700128 t.destroy();
Mathew Inwood29721c22011-06-29 17:55:24 +0100129 } else {
130 if (LOGD_ENABLED) Log.d(LOGTAG, "Ignored discard request " + id);
Michael Kolb14612442011-06-24 13:06:29 -0700131 }
132 }
133
134 /**
135 * Return a preloaded tab, and remove it from the preloader. This is used when the
136 * view is about to be displayed.
137 */
Mathew Inwood29721c22011-06-29 17:55:24 +0100138 public PreloadedTabControl getPreloadedTab(String id) {
Michael Kolb14612442011-06-24 13:06:29 -0700139 PreloaderSession s = takeSession(id);
140 if (LOGD_ENABLED) Log.d(LOGTAG, "Showing preload session " + id + "=" + s);
Mathew Inwood29721c22011-06-29 17:55:24 +0100141 return s == null ? null : s.getTabControl();
Michael Kolb14612442011-06-24 13:06:29 -0700142 }
143
144 private class PreloaderSession {
145 private final String mId;
Mathew Inwood29721c22011-06-29 17:55:24 +0100146 private final PreloadedTabControl mTabControl;
Michael Kolb14612442011-06-24 13:06:29 -0700147
148 private final Runnable mTimeoutTask = new Runnable(){
149 @Override
150 public void run() {
151 if (LOGD_ENABLED) Log.d(LOGTAG, "Preload session timeout " + mId);
152 discardPreload(mId);
153 }};
154
155 public PreloaderSession(String id) {
156 mId = id;
Mathew Inwood29721c22011-06-29 17:55:24 +0100157 mTabControl = new PreloadedTabControl(
158 new Tab(new PreloadController(mContext), mFactory.createWebView(false)));
Michael Kolb14612442011-06-24 13:06:29 -0700159 touch();
160 }
161
162 public void cancelTimeout() {
163 mHandler.removeCallbacks(mTimeoutTask);
164 }
165
166 public void touch() {
167 cancelTimeout();
168 mHandler.postDelayed(mTimeoutTask, PRERENDER_TIMEOUT_MILLIS);
169 }
170
Mathew Inwood29721c22011-06-29 17:55:24 +0100171 public PreloadedTabControl getTabControl() {
172 return mTabControl;
Michael Kolb14612442011-06-24 13:06:29 -0700173 }
174
Mathew Inwoode1dbb952011-07-08 17:27:38 +0100175 public WebView getWebView() {
176 Tab t = mTabControl.getTab();
177 return t == null? null : t.getWebView();
178 }
179
Michael Kolb14612442011-06-24 13:06:29 -0700180 }
181
182}