Preloader.java revision e1dbb956d762c3f07033f247c05270a9882a79a7
1/* 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; 21import android.util.Log; 22import android.webkit.WebView; 23 24import java.util.HashMap; 25import java.util.Map; 26 27/** 28 * Singleton class for handling preload requests. 29 */ 30public class Preloader { 31 32 private final static String LOGTAG = "browser.preloader"; 33 private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED; 34 35 private static final int PRERENDER_TIMEOUT_MILLIS = 30 * 1000; // 30s 36 37 private static Preloader sInstance; 38 39 private final Context mContext; 40 private final Handler mHandler; 41 private final BrowserWebViewFactory mFactory; 42 private final HashMap<String, PreloaderSession> mSessions; 43 44 public static void initialize(Context context) { 45 sInstance = new Preloader(context); 46 } 47 48 public static Preloader getInstance() { 49 return sInstance; 50 } 51 52 private Preloader(Context context) { 53 mContext = context; 54 mHandler = new Handler(Looper.getMainLooper()); 55 mSessions = new HashMap<String, PreloaderSession>(); 56 mFactory = new BrowserWebViewFactory(context); 57 58 } 59 60 private PreloaderSession getSession(String id) { 61 PreloaderSession s = mSessions.get(id); 62 if (s == null) { 63 if (LOGD_ENABLED) Log.d(LOGTAG, "Create new preload session " + id); 64 s = new PreloaderSession(id); 65 mSessions.put(id, s); 66 WebViewTimersControl.getInstance().onPrerenderStart(s.getWebView()); 67 } 68 return s; 69 } 70 71 private PreloaderSession takeSession(String id) { 72 PreloaderSession s = mSessions.remove(id); 73 if (s != null) { 74 s.cancelTimeout(); 75 } 76 if (mSessions.size() == 0) { 77 WebViewTimersControl.getInstance().onPrerenderDone(s == null ? null : s.getWebView()); 78 } 79 return s; 80 } 81 82 public void handlePreloadRequest(String id, String url, Map<String, String> headers, 83 String searchBoxQuery) { 84 PreloaderSession s = getSession(id); 85 s.touch(); // reset timer 86 PreloadedTabControl tab = s.getTabControl(); 87 if (searchBoxQuery != null) { 88 tab.loadUrlIfChanged(url, headers); 89 tab.setQuery(searchBoxQuery); 90 } else { 91 tab.loadUrl(url, headers); 92 } 93 } 94 95 public void discardPreload(String id) { 96 PreloaderSession s = takeSession(id); 97 if (s != null) { 98 if (LOGD_ENABLED) Log.d(LOGTAG, "Discard preload session " + id); 99 PreloadedTabControl t = s.getTabControl(); 100 t.destroy(); 101 } else { 102 if (LOGD_ENABLED) Log.d(LOGTAG, "Ignored discard request " + id); 103 } 104 } 105 106 /** 107 * Return a preloaded tab, and remove it from the preloader. This is used when the 108 * view is about to be displayed. 109 */ 110 public PreloadedTabControl getPreloadedTab(String id) { 111 PreloaderSession s = takeSession(id); 112 if (LOGD_ENABLED) Log.d(LOGTAG, "Showing preload session " + id + "=" + s); 113 return s == null ? null : s.getTabControl(); 114 } 115 116 private class PreloaderSession { 117 private final String mId; 118 private final PreloadedTabControl mTabControl; 119 120 private final Runnable mTimeoutTask = new Runnable(){ 121 @Override 122 public void run() { 123 if (LOGD_ENABLED) Log.d(LOGTAG, "Preload session timeout " + mId); 124 discardPreload(mId); 125 }}; 126 127 public PreloaderSession(String id) { 128 mId = id; 129 mTabControl = new PreloadedTabControl( 130 new Tab(new PreloadController(mContext), mFactory.createWebView(false))); 131 touch(); 132 } 133 134 public void cancelTimeout() { 135 mHandler.removeCallbacks(mTimeoutTask); 136 } 137 138 public void touch() { 139 cancelTimeout(); 140 mHandler.postDelayed(mTimeoutTask, PRERENDER_TIMEOUT_MILLIS); 141 } 142 143 public PreloadedTabControl getTabControl() { 144 return mTabControl; 145 } 146 147 public WebView getWebView() { 148 Tab t = mTabControl.getTab(); 149 return t == null? null : t.getWebView(); 150 } 151 152 } 153 154} 155