blob: cc71f34341b731392721e5c092fc6db704759913 [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 */
16package com.android.browser;
17
18import android.content.Context;
19import android.os.Handler;
20import android.os.Looper;
Michael Kolb14612442011-06-24 13:06:29 -070021import android.util.Log;
Mathew Inwoode1dbb952011-07-08 17:27:38 +010022import android.webkit.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";
Mathew Inwood29721c22011-06-29 17:55:24 +010032 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) {
52 mContext = context;
53 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
57 }
58
59 private PreloaderSession getSession(String id) {
Narayan Kamathf27b7102011-07-22 13:11:53 +010060 if (mSession == null) {
Michael Kolb14612442011-06-24 13:06:29 -070061 if (LOGD_ENABLED) Log.d(LOGTAG, "Create new preload session " + id);
Narayan Kamathf27b7102011-07-22 13:11:53 +010062 mSession = new PreloaderSession(id);
63 WebViewTimersControl.getInstance().onPrerenderStart(
64 mSession.getWebView());
65 return mSession;
66 } else if (mSession.mId.equals(id)) {
67 if (LOGD_ENABLED) Log.d(LOGTAG, "Returning existing preload session " + id);
68 return mSession;
Michael Kolb14612442011-06-24 13:06:29 -070069 }
Narayan Kamathf27b7102011-07-22 13:11:53 +010070
71 if (LOGD_ENABLED) Log.d(LOGTAG, "Existing session in progress : " + mSession.mId +
72 " returning null.");
73 return null;
Michael Kolb14612442011-06-24 13:06:29 -070074 }
75
76 private PreloaderSession takeSession(String id) {
Narayan Kamathf27b7102011-07-22 13:11:53 +010077 PreloaderSession s = null;
78 if (mSession != null && mSession.mId.equals(id)) {
79 s = mSession;
80 mSession = null;
81 }
82
Michael Kolb14612442011-06-24 13:06:29 -070083 if (s != null) {
84 s.cancelTimeout();
85 }
Narayan Kamathf27b7102011-07-22 13:11:53 +010086
87 WebViewTimersControl.getInstance().onPrerenderDone(s == null ? null : s.getWebView());
Michael Kolb14612442011-06-24 13:06:29 -070088 return s;
89 }
90
Mathew Inwood29721c22011-06-29 17:55:24 +010091 public void handlePreloadRequest(String id, String url, Map<String, String> headers,
92 String searchBoxQuery) {
Michael Kolb14612442011-06-24 13:06:29 -070093 PreloaderSession s = getSession(id);
Narayan Kamathf27b7102011-07-22 13:11:53 +010094 if (s == null) {
95 if (LOGD_ENABLED) Log.d(LOGTAG, "Discarding preload request, existing"
96 + " session in progress");
97 return;
98 }
99
Michael Kolb14612442011-06-24 13:06:29 -0700100 s.touch(); // reset timer
Mathew Inwood29721c22011-06-29 17:55:24 +0100101 PreloadedTabControl tab = s.getTabControl();
102 if (searchBoxQuery != null) {
103 tab.loadUrlIfChanged(url, headers);
104 tab.setQuery(searchBoxQuery);
105 } else {
106 tab.loadUrl(url, headers);
107 }
Michael Kolb14612442011-06-24 13:06:29 -0700108 }
109
110 public void discardPreload(String id) {
111 PreloaderSession s = takeSession(id);
112 if (s != null) {
113 if (LOGD_ENABLED) Log.d(LOGTAG, "Discard preload session " + id);
Mathew Inwood29721c22011-06-29 17:55:24 +0100114 PreloadedTabControl t = s.getTabControl();
Michael Kolb14612442011-06-24 13:06:29 -0700115 t.destroy();
Mathew Inwood29721c22011-06-29 17:55:24 +0100116 } else {
117 if (LOGD_ENABLED) Log.d(LOGTAG, "Ignored discard request " + id);
Michael Kolb14612442011-06-24 13:06:29 -0700118 }
119 }
120
121 /**
122 * Return a preloaded tab, and remove it from the preloader. This is used when the
123 * view is about to be displayed.
124 */
Mathew Inwood29721c22011-06-29 17:55:24 +0100125 public PreloadedTabControl getPreloadedTab(String id) {
Michael Kolb14612442011-06-24 13:06:29 -0700126 PreloaderSession s = takeSession(id);
127 if (LOGD_ENABLED) Log.d(LOGTAG, "Showing preload session " + id + "=" + s);
Mathew Inwood29721c22011-06-29 17:55:24 +0100128 return s == null ? null : s.getTabControl();
Michael Kolb14612442011-06-24 13:06:29 -0700129 }
130
131 private class PreloaderSession {
132 private final String mId;
Mathew Inwood29721c22011-06-29 17:55:24 +0100133 private final PreloadedTabControl mTabControl;
Michael Kolb14612442011-06-24 13:06:29 -0700134
135 private final Runnable mTimeoutTask = new Runnable(){
136 @Override
137 public void run() {
138 if (LOGD_ENABLED) Log.d(LOGTAG, "Preload session timeout " + mId);
139 discardPreload(mId);
140 }};
141
142 public PreloaderSession(String id) {
143 mId = id;
Mathew Inwood29721c22011-06-29 17:55:24 +0100144 mTabControl = new PreloadedTabControl(
145 new Tab(new PreloadController(mContext), mFactory.createWebView(false)));
Michael Kolb14612442011-06-24 13:06:29 -0700146 touch();
147 }
148
149 public void cancelTimeout() {
150 mHandler.removeCallbacks(mTimeoutTask);
151 }
152
153 public void touch() {
154 cancelTimeout();
155 mHandler.postDelayed(mTimeoutTask, PRERENDER_TIMEOUT_MILLIS);
156 }
157
Mathew Inwood29721c22011-06-29 17:55:24 +0100158 public PreloadedTabControl getTabControl() {
159 return mTabControl;
Michael Kolb14612442011-06-24 13:06:29 -0700160 }
161
Mathew Inwoode1dbb952011-07-08 17:27:38 +0100162 public WebView getWebView() {
163 Tab t = mTabControl.getTab();
164 return t == null? null : t.getWebView();
165 }
166
Michael Kolb14612442011-06-24 13:06:29 -0700167 }
168
169}