Wed, 31 Dec 2014 07:22:50 +0100
Correct previous dual key logic pending first delivery installment.
michael@0 | 1 | /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- |
michael@0 | 2 | * This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | package org.mozilla.gecko; |
michael@0 | 7 | |
michael@0 | 8 | import org.mozilla.gecko.db.BrowserDB; |
michael@0 | 9 | import org.mozilla.gecko.gfx.LayerView; |
michael@0 | 10 | import org.mozilla.gecko.mozglue.GeckoLoader; |
michael@0 | 11 | import org.mozilla.gecko.util.Clipboard; |
michael@0 | 12 | import org.mozilla.gecko.util.HardwareUtils; |
michael@0 | 13 | import org.mozilla.gecko.util.GeckoEventListener; |
michael@0 | 14 | import org.mozilla.gecko.util.ThreadUtils; |
michael@0 | 15 | |
michael@0 | 16 | import org.json.JSONException; |
michael@0 | 17 | import org.json.JSONObject; |
michael@0 | 18 | |
michael@0 | 19 | import android.app.Activity; |
michael@0 | 20 | import android.content.Context; |
michael@0 | 21 | import android.content.Intent; |
michael@0 | 22 | import android.content.SharedPreferences; |
michael@0 | 23 | import android.content.res.TypedArray; |
michael@0 | 24 | import android.os.Handler; |
michael@0 | 25 | import android.util.AttributeSet; |
michael@0 | 26 | import android.util.Log; |
michael@0 | 27 | import java.util.ArrayList; |
michael@0 | 28 | import java.util.Collections; |
michael@0 | 29 | import java.util.List; |
michael@0 | 30 | |
michael@0 | 31 | public class GeckoView extends LayerView |
michael@0 | 32 | implements GeckoEventListener, ContextGetter { |
michael@0 | 33 | |
michael@0 | 34 | private static final String DEFAULT_SHARED_PREFERENCES_FILE = "GeckoView"; |
michael@0 | 35 | private static final String LOGTAG = "GeckoView"; |
michael@0 | 36 | |
michael@0 | 37 | private ChromeDelegate mChromeDelegate; |
michael@0 | 38 | private ContentDelegate mContentDelegate; |
michael@0 | 39 | |
michael@0 | 40 | public GeckoView(Context context) { |
michael@0 | 41 | super(context); |
michael@0 | 42 | init(context, null, true); |
michael@0 | 43 | } |
michael@0 | 44 | |
michael@0 | 45 | public GeckoView(Context context, AttributeSet attrs) { |
michael@0 | 46 | super(context, attrs); |
michael@0 | 47 | TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GeckoView); |
michael@0 | 48 | String url = a.getString(R.styleable.GeckoView_url); |
michael@0 | 49 | boolean doInit = a.getBoolean(R.styleable.GeckoView_doinit, true); |
michael@0 | 50 | a.recycle(); |
michael@0 | 51 | init(context, url, doInit); |
michael@0 | 52 | } |
michael@0 | 53 | |
michael@0 | 54 | private void init(Context context, String url, boolean doInit) { |
michael@0 | 55 | // TODO: Fennec currently takes care of its own initialization, so this |
michael@0 | 56 | // flag is a hack used in Fennec to prevent GeckoView initialization. |
michael@0 | 57 | // This should go away once Fennec also uses GeckoView for |
michael@0 | 58 | // initialization. |
michael@0 | 59 | if (!doInit) |
michael@0 | 60 | return; |
michael@0 | 61 | |
michael@0 | 62 | // If running outside of a GeckoActivity (eg, from a library project), |
michael@0 | 63 | // load the native code and disable content providers |
michael@0 | 64 | boolean isGeckoActivity = false; |
michael@0 | 65 | try { |
michael@0 | 66 | isGeckoActivity = context instanceof GeckoActivity; |
michael@0 | 67 | } catch (NoClassDefFoundError ex) {} |
michael@0 | 68 | |
michael@0 | 69 | if (!isGeckoActivity) { |
michael@0 | 70 | // Set the GeckoInterface if the context is an activity and the GeckoInterface |
michael@0 | 71 | // has not already been set |
michael@0 | 72 | if (context instanceof Activity && getGeckoInterface() == null) { |
michael@0 | 73 | setGeckoInterface(new BaseGeckoInterface(context)); |
michael@0 | 74 | } |
michael@0 | 75 | |
michael@0 | 76 | Clipboard.init(context); |
michael@0 | 77 | HardwareUtils.init(context); |
michael@0 | 78 | |
michael@0 | 79 | // If you want to use GeckoNetworkManager, start it. |
michael@0 | 80 | |
michael@0 | 81 | GeckoLoader.loadMozGlue(); |
michael@0 | 82 | BrowserDB.setEnableContentProviders(false); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | if (url != null) { |
michael@0 | 86 | GeckoThread.setUri(url); |
michael@0 | 87 | GeckoThread.setAction(Intent.ACTION_VIEW); |
michael@0 | 88 | GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(url)); |
michael@0 | 89 | } |
michael@0 | 90 | GeckoAppShell.setContextGetter(this); |
michael@0 | 91 | if (context instanceof Activity) { |
michael@0 | 92 | Tabs tabs = Tabs.getInstance(); |
michael@0 | 93 | tabs.attachToContext(context); |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | GeckoAppShell.registerEventListener("Gecko:Ready", this); |
michael@0 | 97 | GeckoAppShell.registerEventListener("Content:StateChange", this); |
michael@0 | 98 | GeckoAppShell.registerEventListener("Content:LoadError", this); |
michael@0 | 99 | GeckoAppShell.registerEventListener("Content:PageShow", this); |
michael@0 | 100 | GeckoAppShell.registerEventListener("DOMTitleChanged", this); |
michael@0 | 101 | GeckoAppShell.registerEventListener("Link:Favicon", this); |
michael@0 | 102 | GeckoAppShell.registerEventListener("Prompt:Show", this); |
michael@0 | 103 | GeckoAppShell.registerEventListener("Prompt:ShowTop", this); |
michael@0 | 104 | |
michael@0 | 105 | ThreadUtils.setUiThread(Thread.currentThread(), new Handler()); |
michael@0 | 106 | initializeView(GeckoAppShell.getEventDispatcher()); |
michael@0 | 107 | |
michael@0 | 108 | if (GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) { |
michael@0 | 109 | // This is the first launch, so finish initialization and go. |
michael@0 | 110 | GeckoProfile profile = GeckoProfile.get(context).forceCreate(); |
michael@0 | 111 | BrowserDB.initialize(profile.getName()); |
michael@0 | 112 | |
michael@0 | 113 | GeckoAppShell.setLayerView(this); |
michael@0 | 114 | GeckoThread.createAndStart(); |
michael@0 | 115 | } else if(GeckoThread.checkLaunchState(GeckoThread.LaunchState.GeckoRunning)) { |
michael@0 | 116 | // If Gecko is already running, that means the Activity was |
michael@0 | 117 | // destroyed, so we need to re-attach Gecko to this GeckoView. |
michael@0 | 118 | connectToGecko(); |
michael@0 | 119 | } |
michael@0 | 120 | } |
michael@0 | 121 | |
michael@0 | 122 | /** |
michael@0 | 123 | * Add a Browser to the GeckoView container. |
michael@0 | 124 | * @param url The URL resource to load into the new Browser. |
michael@0 | 125 | */ |
michael@0 | 126 | public Browser addBrowser(String url) { |
michael@0 | 127 | Tab tab = Tabs.getInstance().loadUrl(url, Tabs.LOADURL_NEW_TAB); |
michael@0 | 128 | if (tab != null) { |
michael@0 | 129 | return new Browser(tab.getId()); |
michael@0 | 130 | } |
michael@0 | 131 | return null; |
michael@0 | 132 | } |
michael@0 | 133 | |
michael@0 | 134 | /** |
michael@0 | 135 | * Remove a Browser from the GeckoView container. |
michael@0 | 136 | * @param browser The Browser to remove. |
michael@0 | 137 | */ |
michael@0 | 138 | public void removeBrowser(Browser browser) { |
michael@0 | 139 | Tab tab = Tabs.getInstance().getTab(browser.getId()); |
michael@0 | 140 | if (tab != null) { |
michael@0 | 141 | Tabs.getInstance().closeTab(tab); |
michael@0 | 142 | } |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | /** |
michael@0 | 146 | * Set the active/visible Browser. |
michael@0 | 147 | * @param browser The Browser to make selected. |
michael@0 | 148 | */ |
michael@0 | 149 | public void setCurrentBrowser(Browser browser) { |
michael@0 | 150 | Tab tab = Tabs.getInstance().getTab(browser.getId()); |
michael@0 | 151 | if (tab != null) { |
michael@0 | 152 | Tabs.getInstance().selectTab(tab.getId()); |
michael@0 | 153 | } |
michael@0 | 154 | } |
michael@0 | 155 | |
michael@0 | 156 | /** |
michael@0 | 157 | * Get the active/visible Browser. |
michael@0 | 158 | * @return The current selected Browser. |
michael@0 | 159 | */ |
michael@0 | 160 | public Browser getCurrentBrowser() { |
michael@0 | 161 | Tab tab = Tabs.getInstance().getSelectedTab(); |
michael@0 | 162 | if (tab != null) { |
michael@0 | 163 | return new Browser(tab.getId()); |
michael@0 | 164 | } |
michael@0 | 165 | return null; |
michael@0 | 166 | } |
michael@0 | 167 | |
michael@0 | 168 | /** |
michael@0 | 169 | * Get the list of current Browsers in the GeckoView container. |
michael@0 | 170 | * @return An unmodifiable List of Browser objects. |
michael@0 | 171 | */ |
michael@0 | 172 | public List<Browser> getBrowsers() { |
michael@0 | 173 | ArrayList<Browser> browsers = new ArrayList<Browser>(); |
michael@0 | 174 | Iterable<Tab> tabs = Tabs.getInstance().getTabsInOrder(); |
michael@0 | 175 | for (Tab tab : tabs) { |
michael@0 | 176 | browsers.add(new Browser(tab.getId())); |
michael@0 | 177 | } |
michael@0 | 178 | return Collections.unmodifiableList(browsers); |
michael@0 | 179 | } |
michael@0 | 180 | |
michael@0 | 181 | /** |
michael@0 | 182 | * Not part of the public API. Ignore. |
michael@0 | 183 | */ |
michael@0 | 184 | public void handleMessage(final String event, final JSONObject message) { |
michael@0 | 185 | ThreadUtils.postToUiThread(new Runnable() { |
michael@0 | 186 | @Override |
michael@0 | 187 | public void run() { |
michael@0 | 188 | try { |
michael@0 | 189 | if (event.equals("Gecko:Ready")) { |
michael@0 | 190 | GeckoView.this.handleReady(message); |
michael@0 | 191 | } else if (event.equals("Content:StateChange")) { |
michael@0 | 192 | GeckoView.this.handleStateChange(message); |
michael@0 | 193 | } else if (event.equals("Content:LoadError")) { |
michael@0 | 194 | GeckoView.this.handleLoadError(message); |
michael@0 | 195 | } else if (event.equals("Content:PageShow")) { |
michael@0 | 196 | GeckoView.this.handlePageShow(message); |
michael@0 | 197 | } else if (event.equals("DOMTitleChanged")) { |
michael@0 | 198 | GeckoView.this.handleTitleChanged(message); |
michael@0 | 199 | } else if (event.equals("Link:Favicon")) { |
michael@0 | 200 | GeckoView.this.handleLinkFavicon(message); |
michael@0 | 201 | } else if (event.equals("Prompt:Show") || event.equals("Prompt:ShowTop")) { |
michael@0 | 202 | GeckoView.this.handlePrompt(message); |
michael@0 | 203 | } |
michael@0 | 204 | } catch (Exception e) { |
michael@0 | 205 | Log.w(LOGTAG, "handleMessage threw for " + event, e); |
michael@0 | 206 | } |
michael@0 | 207 | } |
michael@0 | 208 | }); |
michael@0 | 209 | } |
michael@0 | 210 | |
michael@0 | 211 | private void connectToGecko() { |
michael@0 | 212 | GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoRunning); |
michael@0 | 213 | Tab selectedTab = Tabs.getInstance().getSelectedTab(); |
michael@0 | 214 | if (selectedTab != null) |
michael@0 | 215 | Tabs.getInstance().notifyListeners(selectedTab, Tabs.TabEvents.SELECTED); |
michael@0 | 216 | geckoConnected(); |
michael@0 | 217 | GeckoAppShell.setLayerClient(getLayerClientObject()); |
michael@0 | 218 | GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Viewport:Flush", null)); |
michael@0 | 219 | } |
michael@0 | 220 | |
michael@0 | 221 | private void handleReady(final JSONObject message) { |
michael@0 | 222 | connectToGecko(); |
michael@0 | 223 | |
michael@0 | 224 | if (mChromeDelegate != null) { |
michael@0 | 225 | mChromeDelegate.onReady(this); |
michael@0 | 226 | } |
michael@0 | 227 | } |
michael@0 | 228 | |
michael@0 | 229 | private void handleStateChange(final JSONObject message) throws JSONException { |
michael@0 | 230 | int state = message.getInt("state"); |
michael@0 | 231 | if ((state & GeckoAppShell.WPL_STATE_IS_NETWORK) != 0) { |
michael@0 | 232 | if ((state & GeckoAppShell.WPL_STATE_START) != 0) { |
michael@0 | 233 | if (mContentDelegate != null) { |
michael@0 | 234 | int id = message.getInt("tabID"); |
michael@0 | 235 | mContentDelegate.onPageStart(this, new Browser(id), message.getString("uri")); |
michael@0 | 236 | } |
michael@0 | 237 | } else if ((state & GeckoAppShell.WPL_STATE_STOP) != 0) { |
michael@0 | 238 | if (mContentDelegate != null) { |
michael@0 | 239 | int id = message.getInt("tabID"); |
michael@0 | 240 | mContentDelegate.onPageStop(this, new Browser(id), message.getBoolean("success")); |
michael@0 | 241 | } |
michael@0 | 242 | } |
michael@0 | 243 | } |
michael@0 | 244 | } |
michael@0 | 245 | |
michael@0 | 246 | private void handleLoadError(final JSONObject message) throws JSONException { |
michael@0 | 247 | if (mContentDelegate != null) { |
michael@0 | 248 | int id = message.getInt("tabID"); |
michael@0 | 249 | mContentDelegate.onPageStop(GeckoView.this, new Browser(id), false); |
michael@0 | 250 | } |
michael@0 | 251 | } |
michael@0 | 252 | |
michael@0 | 253 | private void handlePageShow(final JSONObject message) throws JSONException { |
michael@0 | 254 | if (mContentDelegate != null) { |
michael@0 | 255 | int id = message.getInt("tabID"); |
michael@0 | 256 | mContentDelegate.onPageShow(GeckoView.this, new Browser(id)); |
michael@0 | 257 | } |
michael@0 | 258 | } |
michael@0 | 259 | |
michael@0 | 260 | private void handleTitleChanged(final JSONObject message) throws JSONException { |
michael@0 | 261 | if (mContentDelegate != null) { |
michael@0 | 262 | int id = message.getInt("tabID"); |
michael@0 | 263 | mContentDelegate.onReceivedTitle(GeckoView.this, new Browser(id), message.getString("title")); |
michael@0 | 264 | } |
michael@0 | 265 | } |
michael@0 | 266 | |
michael@0 | 267 | private void handleLinkFavicon(final JSONObject message) throws JSONException { |
michael@0 | 268 | if (mContentDelegate != null) { |
michael@0 | 269 | int id = message.getInt("tabID"); |
michael@0 | 270 | mContentDelegate.onReceivedFavicon(GeckoView.this, new Browser(id), message.getString("href"), message.getInt("size")); |
michael@0 | 271 | } |
michael@0 | 272 | } |
michael@0 | 273 | |
michael@0 | 274 | private void handlePrompt(final JSONObject message) throws JSONException { |
michael@0 | 275 | if (mChromeDelegate != null) { |
michael@0 | 276 | String hint = message.optString("hint"); |
michael@0 | 277 | if ("alert".equals(hint)) { |
michael@0 | 278 | String text = message.optString("text"); |
michael@0 | 279 | mChromeDelegate.onAlert(GeckoView.this, null, text, new PromptResult(message.optString("guid"))); |
michael@0 | 280 | } else if ("confirm".equals(hint)) { |
michael@0 | 281 | String text = message.optString("text"); |
michael@0 | 282 | mChromeDelegate.onConfirm(GeckoView.this, null, text, new PromptResult(message.optString("guid"))); |
michael@0 | 283 | } else if ("prompt".equals(hint)) { |
michael@0 | 284 | String text = message.optString("text"); |
michael@0 | 285 | String defaultValue = message.optString("textbox0"); |
michael@0 | 286 | mChromeDelegate.onPrompt(GeckoView.this, null, text, defaultValue, new PromptResult(message.optString("guid"))); |
michael@0 | 287 | } else if ("remotedebug".equals(hint)) { |
michael@0 | 288 | mChromeDelegate.onDebugRequest(GeckoView.this, new PromptResult(message.optString("guid"))); |
michael@0 | 289 | } |
michael@0 | 290 | } |
michael@0 | 291 | } |
michael@0 | 292 | |
michael@0 | 293 | /** |
michael@0 | 294 | * Set the chrome callback handler. |
michael@0 | 295 | * This will replace the current handler. |
michael@0 | 296 | * @param chrome An implementation of GeckoViewChrome. |
michael@0 | 297 | */ |
michael@0 | 298 | public void setChromeDelegate(ChromeDelegate chrome) { |
michael@0 | 299 | mChromeDelegate = chrome; |
michael@0 | 300 | } |
michael@0 | 301 | |
michael@0 | 302 | /** |
michael@0 | 303 | * Set the content callback handler. |
michael@0 | 304 | * This will replace the current handler. |
michael@0 | 305 | * @param content An implementation of ContentDelegate. |
michael@0 | 306 | */ |
michael@0 | 307 | public void setContentDelegate(ContentDelegate content) { |
michael@0 | 308 | mContentDelegate = content; |
michael@0 | 309 | } |
michael@0 | 310 | |
michael@0 | 311 | public static void setGeckoInterface(final BaseGeckoInterface geckoInterface) { |
michael@0 | 312 | GeckoAppShell.setGeckoInterface(geckoInterface); |
michael@0 | 313 | } |
michael@0 | 314 | |
michael@0 | 315 | public static GeckoAppShell.GeckoInterface getGeckoInterface() { |
michael@0 | 316 | return GeckoAppShell.getGeckoInterface(); |
michael@0 | 317 | } |
michael@0 | 318 | |
michael@0 | 319 | protected String getSharedPreferencesFile() { |
michael@0 | 320 | return DEFAULT_SHARED_PREFERENCES_FILE; |
michael@0 | 321 | } |
michael@0 | 322 | |
michael@0 | 323 | public SharedPreferences getSharedPreferences() { |
michael@0 | 324 | return getContext().getSharedPreferences(getSharedPreferencesFile(), 0); |
michael@0 | 325 | } |
michael@0 | 326 | |
michael@0 | 327 | /** |
michael@0 | 328 | * Wrapper for a browser in the GeckoView container. Associated with a browser |
michael@0 | 329 | * element in the Gecko system. |
michael@0 | 330 | */ |
michael@0 | 331 | public class Browser { |
michael@0 | 332 | private final int mId; |
michael@0 | 333 | private Browser(int Id) { |
michael@0 | 334 | mId = Id; |
michael@0 | 335 | } |
michael@0 | 336 | |
michael@0 | 337 | /** |
michael@0 | 338 | * Get the ID of the Browser. This is the same ID used by Gecko for it's underlying |
michael@0 | 339 | * browser element. |
michael@0 | 340 | * @return The integer ID of the Browser. |
michael@0 | 341 | */ |
michael@0 | 342 | private int getId() { |
michael@0 | 343 | return mId; |
michael@0 | 344 | } |
michael@0 | 345 | |
michael@0 | 346 | /** |
michael@0 | 347 | * Load a URL resource into the Browser. |
michael@0 | 348 | * @param url The URL string. |
michael@0 | 349 | */ |
michael@0 | 350 | public void loadUrl(String url) { |
michael@0 | 351 | JSONObject args = new JSONObject(); |
michael@0 | 352 | try { |
michael@0 | 353 | args.put("url", url); |
michael@0 | 354 | args.put("parentId", -1); |
michael@0 | 355 | args.put("newTab", false); |
michael@0 | 356 | args.put("tabID", mId); |
michael@0 | 357 | } catch (Exception e) { |
michael@0 | 358 | Log.w(LOGTAG, "Error building JSON arguments for loadUrl.", e); |
michael@0 | 359 | } |
michael@0 | 360 | GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString())); |
michael@0 | 361 | } |
michael@0 | 362 | |
michael@0 | 363 | /** |
michael@0 | 364 | * Reload the current URL resource into the Browser. The URL is force loaded from the |
michael@0 | 365 | * network and is not pulled from cache. |
michael@0 | 366 | */ |
michael@0 | 367 | public void reload() { |
michael@0 | 368 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 369 | if (tab != null) { |
michael@0 | 370 | tab.doReload(); |
michael@0 | 371 | } |
michael@0 | 372 | } |
michael@0 | 373 | |
michael@0 | 374 | /** |
michael@0 | 375 | * Stop the current loading operation. |
michael@0 | 376 | */ |
michael@0 | 377 | public void stop() { |
michael@0 | 378 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 379 | if (tab != null) { |
michael@0 | 380 | tab.doStop(); |
michael@0 | 381 | } |
michael@0 | 382 | } |
michael@0 | 383 | |
michael@0 | 384 | /** |
michael@0 | 385 | * Check to see if the Browser has session history and can go back to a |
michael@0 | 386 | * previous page. |
michael@0 | 387 | * @return A boolean flag indicating if previous session exists. |
michael@0 | 388 | * This method will likely be removed and replaced by a callback in GeckoViewContent |
michael@0 | 389 | */ |
michael@0 | 390 | public boolean canGoBack() { |
michael@0 | 391 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 392 | if (tab != null) { |
michael@0 | 393 | return tab.canDoBack(); |
michael@0 | 394 | } |
michael@0 | 395 | return false; |
michael@0 | 396 | } |
michael@0 | 397 | |
michael@0 | 398 | /** |
michael@0 | 399 | * Move backward in the session history, if that's possible. |
michael@0 | 400 | */ |
michael@0 | 401 | public void goBack() { |
michael@0 | 402 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 403 | if (tab != null) { |
michael@0 | 404 | tab.doBack(); |
michael@0 | 405 | } |
michael@0 | 406 | } |
michael@0 | 407 | |
michael@0 | 408 | /** |
michael@0 | 409 | * Check to see if the Browser has session history and can go forward to a |
michael@0 | 410 | * new page. |
michael@0 | 411 | * @return A boolean flag indicating if forward session exists. |
michael@0 | 412 | * This method will likely be removed and replaced by a callback in GeckoViewContent |
michael@0 | 413 | */ |
michael@0 | 414 | public boolean canGoForward() { |
michael@0 | 415 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 416 | if (tab != null) { |
michael@0 | 417 | return tab.canDoForward(); |
michael@0 | 418 | } |
michael@0 | 419 | return false; |
michael@0 | 420 | } |
michael@0 | 421 | |
michael@0 | 422 | /** |
michael@0 | 423 | * Move forward in the session history, if that's possible. |
michael@0 | 424 | */ |
michael@0 | 425 | public void goForward() { |
michael@0 | 426 | Tab tab = Tabs.getInstance().getTab(mId); |
michael@0 | 427 | if (tab != null) { |
michael@0 | 428 | tab.doForward(); |
michael@0 | 429 | } |
michael@0 | 430 | } |
michael@0 | 431 | } |
michael@0 | 432 | |
michael@0 | 433 | /* Provides a means for the client to indicate whether a JavaScript |
michael@0 | 434 | * dialog request should proceed. An instance of this class is passed to |
michael@0 | 435 | * various GeckoViewChrome callback actions. |
michael@0 | 436 | */ |
michael@0 | 437 | public class PromptResult { |
michael@0 | 438 | private final int RESULT_OK = 0; |
michael@0 | 439 | private final int RESULT_CANCEL = 1; |
michael@0 | 440 | |
michael@0 | 441 | private final String mGUID; |
michael@0 | 442 | |
michael@0 | 443 | public PromptResult(String guid) { |
michael@0 | 444 | mGUID = guid; |
michael@0 | 445 | } |
michael@0 | 446 | |
michael@0 | 447 | private JSONObject makeResult(int resultCode) { |
michael@0 | 448 | JSONObject result = new JSONObject(); |
michael@0 | 449 | try { |
michael@0 | 450 | result.put("guid", mGUID); |
michael@0 | 451 | result.put("button", resultCode); |
michael@0 | 452 | } catch(JSONException ex) { } |
michael@0 | 453 | return result; |
michael@0 | 454 | } |
michael@0 | 455 | |
michael@0 | 456 | /** |
michael@0 | 457 | * Handle a confirmation response from the user. |
michael@0 | 458 | */ |
michael@0 | 459 | public void confirm() { |
michael@0 | 460 | JSONObject result = makeResult(RESULT_OK); |
michael@0 | 461 | GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Prompt:Reply", result.toString())); |
michael@0 | 462 | } |
michael@0 | 463 | |
michael@0 | 464 | /** |
michael@0 | 465 | * Handle a confirmation response from the user. |
michael@0 | 466 | * @param value String value to return to the browser context. |
michael@0 | 467 | */ |
michael@0 | 468 | public void confirmWithValue(String value) { |
michael@0 | 469 | JSONObject result = makeResult(RESULT_OK); |
michael@0 | 470 | try { |
michael@0 | 471 | result.put("textbox0", value); |
michael@0 | 472 | } catch(JSONException ex) { } |
michael@0 | 473 | GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Prompt:Reply", result.toString())); |
michael@0 | 474 | } |
michael@0 | 475 | |
michael@0 | 476 | /** |
michael@0 | 477 | * Handle a cancellation response from the user. |
michael@0 | 478 | */ |
michael@0 | 479 | public void cancel() { |
michael@0 | 480 | JSONObject result = makeResult(RESULT_CANCEL); |
michael@0 | 481 | GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Prompt:Reply", result.toString())); |
michael@0 | 482 | } |
michael@0 | 483 | } |
michael@0 | 484 | |
michael@0 | 485 | public interface ChromeDelegate { |
michael@0 | 486 | /** |
michael@0 | 487 | * Tell the host application that Gecko is ready to handle requests. |
michael@0 | 488 | * @param view The GeckoView that initiated the callback. |
michael@0 | 489 | */ |
michael@0 | 490 | public void onReady(GeckoView view); |
michael@0 | 491 | |
michael@0 | 492 | /** |
michael@0 | 493 | * Tell the host application to display an alert dialog. |
michael@0 | 494 | * @param view The GeckoView that initiated the callback. |
michael@0 | 495 | * @param browser The Browser that is loading the content. |
michael@0 | 496 | * @param message The string to display in the dialog. |
michael@0 | 497 | * @param result A PromptResult used to send back the result without blocking. |
michael@0 | 498 | * Defaults to cancel requests. |
michael@0 | 499 | */ |
michael@0 | 500 | public void onAlert(GeckoView view, GeckoView.Browser browser, String message, GeckoView.PromptResult result); |
michael@0 | 501 | |
michael@0 | 502 | /** |
michael@0 | 503 | * Tell the host application to display a confirmation dialog. |
michael@0 | 504 | * @param view The GeckoView that initiated the callback. |
michael@0 | 505 | * @param browser The Browser that is loading the content. |
michael@0 | 506 | * @param message The string to display in the dialog. |
michael@0 | 507 | * @param result A PromptResult used to send back the result without blocking. |
michael@0 | 508 | * Defaults to cancel requests. |
michael@0 | 509 | */ |
michael@0 | 510 | public void onConfirm(GeckoView view, GeckoView.Browser browser, String message, GeckoView.PromptResult result); |
michael@0 | 511 | |
michael@0 | 512 | /** |
michael@0 | 513 | * Tell the host application to display an input prompt dialog. |
michael@0 | 514 | * @param view The GeckoView that initiated the callback. |
michael@0 | 515 | * @param browser The Browser that is loading the content. |
michael@0 | 516 | * @param message The string to display in the dialog. |
michael@0 | 517 | * @param defaultValue The string to use as default input. |
michael@0 | 518 | * @param result A PromptResult used to send back the result without blocking. |
michael@0 | 519 | * Defaults to cancel requests. |
michael@0 | 520 | */ |
michael@0 | 521 | public void onPrompt(GeckoView view, GeckoView.Browser browser, String message, String defaultValue, GeckoView.PromptResult result); |
michael@0 | 522 | |
michael@0 | 523 | /** |
michael@0 | 524 | * Tell the host application to display a remote debugging request dialog. |
michael@0 | 525 | * @param view The GeckoView that initiated the callback. |
michael@0 | 526 | * @param result A PromptResult used to send back the result without blocking. |
michael@0 | 527 | * Defaults to cancel requests. |
michael@0 | 528 | */ |
michael@0 | 529 | public void onDebugRequest(GeckoView view, GeckoView.PromptResult result); |
michael@0 | 530 | } |
michael@0 | 531 | |
michael@0 | 532 | public interface ContentDelegate { |
michael@0 | 533 | /** |
michael@0 | 534 | * A Browser has started loading content from the network. |
michael@0 | 535 | * @param view The GeckoView that initiated the callback. |
michael@0 | 536 | * @param browser The Browser that is loading the content. |
michael@0 | 537 | * @param url The resource being loaded. |
michael@0 | 538 | */ |
michael@0 | 539 | public void onPageStart(GeckoView view, GeckoView.Browser browser, String url); |
michael@0 | 540 | |
michael@0 | 541 | /** |
michael@0 | 542 | * A Browser has finished loading content from the network. |
michael@0 | 543 | * @param view The GeckoView that initiated the callback. |
michael@0 | 544 | * @param browser The Browser that was loading the content. |
michael@0 | 545 | * @param success Whether the page loaded successfully or an error occured. |
michael@0 | 546 | */ |
michael@0 | 547 | public void onPageStop(GeckoView view, GeckoView.Browser browser, boolean success); |
michael@0 | 548 | |
michael@0 | 549 | /** |
michael@0 | 550 | * A Browser is displaying content. This page could have been loaded via |
michael@0 | 551 | * network or from the session history. |
michael@0 | 552 | * @param view The GeckoView that initiated the callback. |
michael@0 | 553 | * @param browser The Browser that is showing the content. |
michael@0 | 554 | */ |
michael@0 | 555 | public void onPageShow(GeckoView view, GeckoView.Browser browser); |
michael@0 | 556 | |
michael@0 | 557 | /** |
michael@0 | 558 | * A page title was discovered in the content or updated after the content |
michael@0 | 559 | * loaded. |
michael@0 | 560 | * @param view The GeckoView that initiated the callback. |
michael@0 | 561 | * @param browser The Browser that is showing the content. |
michael@0 | 562 | * @param title The title sent from the content. |
michael@0 | 563 | */ |
michael@0 | 564 | public void onReceivedTitle(GeckoView view, GeckoView.Browser browser, String title); |
michael@0 | 565 | |
michael@0 | 566 | /** |
michael@0 | 567 | * A link element was discovered in the content or updated after the content |
michael@0 | 568 | * loaded that specifies a favicon. |
michael@0 | 569 | * @param view The GeckoView that initiated the callback. |
michael@0 | 570 | * @param browser The Browser that is showing the content. |
michael@0 | 571 | * @param url The href of the link element specifying the favicon. |
michael@0 | 572 | * @param size The maximum size specified for the favicon, or -1 for any size. |
michael@0 | 573 | */ |
michael@0 | 574 | public void onReceivedFavicon(GeckoView view, GeckoView.Browser browser, String url, int size); |
michael@0 | 575 | } |
michael@0 | 576 | |
michael@0 | 577 | } |