• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
16 package com.android.browser;
17 
18 import android.content.Context;
19 import android.os.Handler;
20 import android.os.Looper;
21 import android.util.Log;
22 import android.webkit.WebView;
23 
24 import java.util.Map;
25 
26 /**
27  * Singleton class for handling preload requests.
28  */
29 public class Preloader {
30 
31     private final static String LOGTAG = "browser.preloader";
32     private final static boolean LOGD_ENABLED = com.android.browser.Browser.LOGD_ENABLED;
33 
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;
41     private volatile PreloaderSession mSession;
42 
initialize(Context context)43     public static void initialize(Context context) {
44         sInstance = new Preloader(context);
45     }
46 
getInstance()47     public static Preloader getInstance() {
48         return sInstance;
49     }
50 
Preloader(Context context)51     private Preloader(Context context) {
52         mContext = context.getApplicationContext();
53         mHandler = new Handler(Looper.getMainLooper());
54         mSession = null;
55         mFactory = new BrowserWebViewFactory(context);
56 
57     }
58 
getSession(String id)59     private PreloaderSession getSession(String id) {
60         if (mSession == null) {
61             if (LOGD_ENABLED) Log.d(LOGTAG, "Create new preload session " + id);
62             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;
69         }
70 
71         if (LOGD_ENABLED) Log.d(LOGTAG, "Existing session in progress : " + mSession.mId +
72                 " returning null.");
73         return null;
74     }
75 
takeSession(String id)76     private PreloaderSession takeSession(String id) {
77         PreloaderSession s = null;
78         if (mSession != null && mSession.mId.equals(id)) {
79             s = mSession;
80             mSession = null;
81         }
82 
83         if (s != null) {
84             s.cancelTimeout();
85         }
86 
87         return s;
88     }
89 
handlePreloadRequest(String id, String url, Map<String, String> headers, String searchBoxQuery)90     public void handlePreloadRequest(String id, String url, Map<String, String> headers,
91             String searchBoxQuery) {
92         PreloaderSession s = getSession(id);
93         if (s == null) {
94             if (LOGD_ENABLED) Log.d(LOGTAG, "Discarding preload request, existing"
95                     + " session in progress");
96             return;
97         }
98 
99         s.touch(); // reset timer
100         PreloadedTabControl tab = s.getTabControl();
101         if (searchBoxQuery != null) {
102             tab.loadUrlIfChanged(url, headers);
103             tab.setQuery(searchBoxQuery);
104         } else {
105             tab.loadUrl(url, headers);
106         }
107     }
108 
cancelSearchBoxPreload(String id)109     public void cancelSearchBoxPreload(String id) {
110         PreloaderSession s = getSession(id);
111         if (s != null) {
112             s.touch(); // reset timer
113             PreloadedTabControl tab = s.getTabControl();
114             tab.searchBoxCancel();
115         }
116     }
117 
discardPreload(String id)118     public void discardPreload(String id) {
119         PreloaderSession s = takeSession(id);
120         if (s != null) {
121             if (LOGD_ENABLED) Log.d(LOGTAG, "Discard preload session " + id);
122             WebViewTimersControl.getInstance().onPrerenderDone(s == null ? null : s.getWebView());
123             PreloadedTabControl t = s.getTabControl();
124             t.destroy();
125         } else {
126             if (LOGD_ENABLED) Log.d(LOGTAG, "Ignored discard request " + id);
127         }
128     }
129 
130     /**
131      * Return a preloaded tab, and remove it from the preloader. This is used when the
132      * view is about to be displayed.
133      */
getPreloadedTab(String id)134     public PreloadedTabControl getPreloadedTab(String id) {
135         PreloaderSession s = takeSession(id);
136         if (LOGD_ENABLED) Log.d(LOGTAG, "Showing preload session " + id + "=" + s);
137         return s == null ? null : s.getTabControl();
138     }
139 
140     private class PreloaderSession {
141         private final String mId;
142         private final PreloadedTabControl mTabControl;
143 
144         private final Runnable mTimeoutTask = new Runnable(){
145             @Override
146             public void run() {
147                 if (LOGD_ENABLED) Log.d(LOGTAG, "Preload session timeout " + mId);
148                 discardPreload(mId);
149             }};
150 
PreloaderSession(String id)151         public PreloaderSession(String id) {
152             mId = id;
153             mTabControl = new PreloadedTabControl(
154                     new Tab(new PreloadController(mContext), mFactory.createWebView(false)));
155             touch();
156         }
157 
cancelTimeout()158         public void cancelTimeout() {
159             mHandler.removeCallbacks(mTimeoutTask);
160         }
161 
touch()162         public void touch() {
163             cancelTimeout();
164             mHandler.postDelayed(mTimeoutTask, PRERENDER_TIMEOUT_MILLIS);
165         }
166 
getTabControl()167         public PreloadedTabControl getTabControl() {
168             return mTabControl;
169         }
170 
getWebView()171         public WebView getWebView() {
172             Tab t = mTabControl.getTab();
173             return t == null? null : t.getWebView();
174         }
175 
176     }
177 
178 }
179