JWebCoreJavaBridge.java revision 1155e18ccc1c5dd486aa6e6648f91cbbf1521b92
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 value The cookie string to be stored.
139     */
140    private void setCookies(String url, String value) {
141        if (value.contains("\r") || value.contains("\n")) {
142            // for security reason, filter out '\r' and '\n' from the cookie
143            int size = value.length();
144            StringBuilder buffer = new StringBuilder(size);
145            int i = 0;
146            while (i != -1 && i < size) {
147                int ir = value.indexOf('\r', i);
148                int in = value.indexOf('\n', i);
149                int newi = (ir == -1) ? in : (in == -1 ? ir : (ir < in ? ir
150                        : in));
151                if (newi > i) {
152                    buffer.append(value.subSequence(i, newi));
153                } else if (newi == -1) {
154                    buffer.append(value.subSequence(i, size));
155                    break;
156                }
157                i = newi + 1;
158            }
159            value = buffer.toString();
160        }
161        CookieManager.getInstance().setCookie(url, value);
162    }
163
164    /**
165     * Retrieve the cookie string for the given url.
166     * @param url The resource's url.
167     * @return A String representing the cookies for the given resource url.
168     */
169    private String cookies(String url) {
170        return CookieManager.getInstance().getCookie(url);
171    }
172
173    /**
174     * Returns whether cookies are enabled or not.
175     */
176    private boolean cookiesEnabled() {
177        return CookieManager.getInstance().acceptCookie();
178    }
179
180    /**
181     * Returns an array of plugin directoies
182     */
183    private String[] getPluginDirectories() {
184        return PluginManager.getInstance(null).getPluginDirecoties();
185    }
186
187    /**
188     * setSharedTimer
189     * @param timemillis The relative time when the timer should fire
190     */
191    private void setSharedTimer(long timemillis) {
192        if (DebugFlags.J_WEB_CORE_JAVA_BRIDGE) Log.v(LOGTAG, "setSharedTimer " + timemillis);
193
194        if (timemillis <= 0) {
195            // we don't accumulate the sharedTimer unless it is a delayed
196            // request. This way we won't flood the message queue with
197            // WebKit messages. This should improve the browser's
198            // responsiveness to key events.
199            if (mHasInstantTimer) {
200                return;
201            } else {
202                mHasInstantTimer = true;
203                Message msg = obtainMessage(TIMER_MESSAGE);
204                sendMessageDelayed(msg, timemillis);
205            }
206        } else {
207            Message msg = obtainMessage(TIMER_MESSAGE);
208            sendMessageDelayed(msg, timemillis);
209        }
210    }
211
212    /**
213     * Stop the shared timer.
214     */
215    private void stopSharedTimer() {
216        if (DebugFlags.J_WEB_CORE_JAVA_BRIDGE) {
217            Log.v(LOGTAG, "stopSharedTimer removing all timers");
218        }
219        removeMessages(TIMER_MESSAGE);
220        mHasInstantTimer = false;
221        mHasDeferredTimers = false;
222    }
223
224    private String[] getKeyStrengthList() {
225        // FIXME: fake the list for now
226        String[] list = new String[2];
227        list[0] = "1024";
228        list[1] = "512";
229        return list;
230    }
231
232    private String getSignedPublicKey(int index, String challenge, String url) {
233        // FIXME: do nothing for now
234        Log.w(LOGTAG, "getSignedPublicKey for " + index + " and challenge="
235                + challenge + " and url=" + url);
236        return "";
237    }
238
239    private native void nativeConstructor();
240    private native void nativeFinalize();
241    private native void sharedTimerFired();
242    private native void nativeUpdatePluginDirectories(String[] directories,
243            boolean reload);
244    public native void setNetworkOnLine(boolean online);
245}
246