JWebCoreJavaBridge.java revision e3a6cf3eaab04dede374a3d64cb8db2d20e3820e
1/*
2 * Copyright (C) 2006 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
17package android.webkit;
18
19import android.os.Handler;
20import android.os.Message;
21import android.util.Log;
22
23final class JWebCoreJavaBridge extends Handler {
24    // Identifier for the timer message.
25    private static final int TIMER_MESSAGE = 1;
26    // ID for servicing functionptr queue
27    private static final int FUNCPTR_MESSAGE = 2;
28    // Log system identifier.
29    private static final String LOGTAG = "webkit-timers";
30
31    // Native object pointer for interacting in native code.
32    private int mNativeBridge;
33    // Instant timer is used to implement a timer that needs to fire almost
34    // immediately.
35    private boolean mHasInstantTimer;
36
37    // Reference count the pause/resume of timers
38    private int mPauseTimerRefCount;
39
40    private boolean mTimerPaused;
41    private boolean mHasDeferredTimers;
42
43    /* package */
44    static final int REFRESH_PLUGINS = 100;
45
46    /**
47     * Construct a new JWebCoreJavaBridge to interface with
48     * WebCore timers and cookies.
49     */
50    public JWebCoreJavaBridge() {
51        nativeConstructor();
52    }
53
54    @Override
55    protected void finalize() {
56        nativeFinalize();
57    }
58
59    /**
60     * Call native timer callbacks.
61     */
62    private void fireSharedTimer() {
63        PerfChecker checker = new PerfChecker();
64        // clear the flag so that sharedTimerFired() can set a new timer
65        mHasInstantTimer = false;
66        sharedTimerFired();
67        checker.responseAlert("sharedTimer");
68    }
69
70    /**
71     * handleMessage
72     * @param msg The dispatched message.
73     *
74     * The only accepted message currently is TIMER_MESSAGE
75     */
76    @Override
77    public void handleMessage(Message msg) {
78        switch (msg.what) {
79            case TIMER_MESSAGE: {
80                if (mTimerPaused) {
81                    mHasDeferredTimers = true;
82                } else {
83                    fireSharedTimer();
84                }
85                break;
86            }
87            case FUNCPTR_MESSAGE:
88                nativeServiceFuncPtrQueue();
89                break;
90            case REFRESH_PLUGINS:
91                nativeUpdatePluginDirectories(PluginManager.getInstance(null)
92                        .getPluginDirecoties(), ((Boolean) msg.obj)
93                        .booleanValue());
94                break;
95        }
96    }
97
98    // called from JNI side
99    private void signalServiceFuncPtrQueue() {
100        Message msg = obtainMessage(FUNCPTR_MESSAGE);
101        sendMessage(msg);
102    }
103
104    private native void nativeServiceFuncPtrQueue();
105
106    /**
107     * Pause all timers.
108     */
109    public void pause() {
110        if (--mPauseTimerRefCount == 0) {
111            mTimerPaused = true;
112            mHasDeferredTimers = false;
113        }
114    }
115
116    /**
117     * Resume all timers.
118     */
119    public void resume() {
120        if (++mPauseTimerRefCount == 1) {
121           mTimerPaused = false;
122           if (mHasDeferredTimers) {
123               mHasDeferredTimers = false;
124               fireSharedTimer();
125           }
126        }
127    }
128
129    /**
130     * Set WebCore cache size.
131     * @param bytes The cache size in bytes.
132     */
133    public native void setCacheSize(int bytes);
134
135    /**
136     * Store a cookie string associated with a url.
137     * @param url The url to be used as a key for the cookie.
138     * @param docUrl The policy base url used by WebCore.
139     * @param value The cookie string to be stored.
140     */
141    private void setCookies(String url, String docUrl, String value) {
142        if (value.contains("\r") || value.contains("\n")) {
143            // for security reason, filter out '\r' and '\n' from the cookie
144            int size = value.length();
145            StringBuilder buffer = new StringBuilder(size);
146            int i = 0;
147            while (i != -1 && i < size) {
148                int ir = value.indexOf('\r', i);
149                int in = value.indexOf('\n', i);
150                int newi = (ir == -1) ? in : (in == -1 ? ir : (ir < in ? ir
151                        : in));
152                if (newi > i) {
153                    buffer.append(value.subSequence(i, newi));
154                } else if (newi == -1) {
155                    buffer.append(value.subSequence(i, size));
156                    break;
157                }
158                i = newi + 1;
159            }
160            value = buffer.toString();
161        }
162        CookieManager.getInstance().setCookie(url, value);
163    }
164
165    /**
166     * Retrieve the cookie string for the given url.
167     * @param url The resource's url.
168     * @return A String representing the cookies for the given resource url.
169     */
170    private String cookies(String url) {
171        return CookieManager.getInstance().getCookie(url);
172    }
173
174    /**
175     * Returns whether cookies are enabled or not.
176     */
177    private boolean cookiesEnabled() {
178        return CookieManager.getInstance().acceptCookie();
179    }
180
181    /**
182     * Returns an array of plugin directoies
183     */
184    private String[] getPluginDirectories() {
185        return PluginManager.getInstance(null).getPluginDirecoties();
186    }
187
188    /**
189     * setSharedTimer
190     * @param timemillis The relative time when the timer should fire
191     */
192    private void setSharedTimer(long timemillis) {
193        if (DebugFlags.J_WEB_CORE_JAVA_BRIDGE) Log.v(LOGTAG, "setSharedTimer " + timemillis);
194
195        if (timemillis <= 0) {
196            // we don't accumulate the sharedTimer unless it is a delayed
197            // request. This way we won't flood the message queue with
198            // WebKit messages. This should improve the browser's
199            // responsiveness to key events.
200            if (mHasInstantTimer) {
201                return;
202            } else {
203                mHasInstantTimer = true;
204                Message msg = obtainMessage(TIMER_MESSAGE);
205                sendMessageDelayed(msg, timemillis);
206            }
207        } else {
208            Message msg = obtainMessage(TIMER_MESSAGE);
209            sendMessageDelayed(msg, timemillis);
210        }
211    }
212
213    /**
214     * Stop the shared timer.
215     */
216    private void stopSharedTimer() {
217        if (DebugFlags.J_WEB_CORE_JAVA_BRIDGE) {
218            Log.v(LOGTAG, "stopSharedTimer removing all timers");
219        }
220        removeMessages(TIMER_MESSAGE);
221        mHasInstantTimer = false;
222        mHasDeferredTimers = false;
223    }
224
225    private String[] getKeyStrengthList() {
226        // FIXME: fake the list for now
227        String[] list = new String[2];
228        list[0] = "1024";
229        list[1] = "512";
230        return list;
231    }
232
233    private String getSignedPublicKey(int index, String challenge, String url) {
234        // FIXME: do nothing for now
235        Log.w(LOGTAG, "getSignedPublicKey for " + index + " and challenge="
236                + challenge + " and url=" + url);
237        return "";
238    }
239
240    private native void nativeConstructor();
241    private native void nativeFinalize();
242    private native void sharedTimerFired();
243    private native void nativeUpdatePluginDirectories(String[] directories,
244            boolean reload);
245    public native void setNetworkOnLine(boolean online);
246}
247