| /* |
| * Copyright (C) 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. |
| */ |
| package com.android.browser; |
| |
| import android.content.Context; |
| import android.os.Handler; |
| import android.os.Looper; |
| import android.util.Log; |
| import android.webkit.WebView; |
| |
| import java.util.Map; |
| |
| /** |
| * Singleton class for handling preload requests. |
| */ |
| public class Preloader { |
| |
| private final static String LOGTAG = "browser.preloader"; |
| private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; |
| |
| private static final int PRERENDER_TIMEOUT_MILLIS = 30 * 1000; // 30s |
| |
| private static Preloader sInstance; |
| |
| private final Context mContext; |
| private final Handler mHandler; |
| private final BrowserWebViewFactory mFactory; |
| private volatile PreloaderSession mSession; |
| |
| public static void initialize(Context context) { |
| sInstance = new Preloader(context); |
| } |
| |
| public static Preloader getInstance() { |
| return sInstance; |
| } |
| |
| private Preloader(Context context) { |
| mContext = context.getApplicationContext(); |
| mHandler = new Handler(Looper.getMainLooper()); |
| mSession = null; |
| mFactory = new BrowserWebViewFactory(context); |
| |
| } |
| |
| private PreloaderSession getSession(String id) { |
| if (mSession == null) { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Create new preload session " + id); |
| mSession = new PreloaderSession(id); |
| WebViewTimersControl.getInstance().onPrerenderStart( |
| mSession.getWebView()); |
| return mSession; |
| } else if (mSession.mId.equals(id)) { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Returning existing preload session " + id); |
| return mSession; |
| } |
| |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Existing session in progress : " + mSession.mId + |
| " returning null."); |
| return null; |
| } |
| |
| private PreloaderSession takeSession(String id) { |
| PreloaderSession s = null; |
| if (mSession != null && mSession.mId.equals(id)) { |
| s = mSession; |
| mSession = null; |
| } |
| |
| if (s != null) { |
| s.cancelTimeout(); |
| } |
| |
| return s; |
| } |
| |
| public void handlePreloadRequest(String id, String url, Map<String, String> headers, |
| String searchBoxQuery) { |
| PreloaderSession s = getSession(id); |
| if (s == null) { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Discarding preload request, existing" |
| + " session in progress"); |
| return; |
| } |
| |
| s.touch(); // reset timer |
| PreloadedTabControl tab = s.getTabControl(); |
| if (searchBoxQuery != null) { |
| tab.loadUrlIfChanged(url, headers); |
| tab.setQuery(searchBoxQuery); |
| } else { |
| tab.loadUrl(url, headers); |
| } |
| } |
| |
| public void cancelSearchBoxPreload(String id) { |
| PreloaderSession s = getSession(id); |
| if (s != null) { |
| s.touch(); // reset timer |
| PreloadedTabControl tab = s.getTabControl(); |
| tab.searchBoxCancel(); |
| } |
| } |
| |
| public void discardPreload(String id) { |
| PreloaderSession s = takeSession(id); |
| if (s != null) { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Discard preload session " + id); |
| WebViewTimersControl.getInstance().onPrerenderDone(s == null ? null : s.getWebView()); |
| PreloadedTabControl t = s.getTabControl(); |
| t.destroy(); |
| } else { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Ignored discard request " + id); |
| } |
| } |
| |
| /** |
| * Return a preloaded tab, and remove it from the preloader. This is used when the |
| * view is about to be displayed. |
| */ |
| public PreloadedTabControl getPreloadedTab(String id) { |
| PreloaderSession s = takeSession(id); |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Showing preload session " + id + "=" + s); |
| return s == null ? null : s.getTabControl(); |
| } |
| |
| private class PreloaderSession { |
| private final String mId; |
| private final PreloadedTabControl mTabControl; |
| |
| private final Runnable mTimeoutTask = new Runnable(){ |
| @Override |
| public void run() { |
| if (LOGD_ENABLED) Log.d(LOGTAG, "Preload session timeout " + mId); |
| discardPreload(mId); |
| }}; |
| |
| public PreloaderSession(String id) { |
| mId = id; |
| mTabControl = new PreloadedTabControl( |
| new Tab(new PreloadController(mContext), mFactory.createWebView(false))); |
| touch(); |
| } |
| |
| public void cancelTimeout() { |
| mHandler.removeCallbacks(mTimeoutTask); |
| } |
| |
| public void touch() { |
| cancelTimeout(); |
| mHandler.postDelayed(mTimeoutTask, PRERENDER_TIMEOUT_MILLIS); |
| } |
| |
| public PreloadedTabControl getTabControl() { |
| return mTabControl; |
| } |
| |
| public WebView getWebView() { |
| Tab t = mTabControl.getTab(); |
| return t == null? null : t.getWebView(); |
| } |
| |
| } |
| |
| } |