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