2013-05-30 04:31:43 +00:00
|
|
|
/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
|
|
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
package org.mozilla.gecko;
|
|
|
|
|
|
|
|
import org.mozilla.gecko.db.BrowserDB;
|
|
|
|
import org.mozilla.gecko.gfx.LayerView;
|
2013-08-23 18:46:05 +00:00
|
|
|
import org.mozilla.gecko.mozglue.GeckoLoader;
|
|
|
|
import org.mozilla.gecko.util.Clipboard;
|
2013-09-05 04:33:11 +00:00
|
|
|
import org.mozilla.gecko.util.HardwareUtils;
|
2013-05-30 04:31:43 +00:00
|
|
|
import org.mozilla.gecko.util.GeckoEventListener;
|
|
|
|
import org.mozilla.gecko.util.ThreadUtils;
|
|
|
|
|
|
|
|
import org.json.JSONObject;
|
|
|
|
|
|
|
|
import android.app.Activity;
|
|
|
|
import android.content.Context;
|
|
|
|
import android.content.Intent;
|
|
|
|
import android.content.res.TypedArray;
|
|
|
|
import android.graphics.Canvas;
|
|
|
|
import android.graphics.Paint;
|
|
|
|
import android.net.Uri;
|
|
|
|
import android.os.Bundle;
|
2013-08-23 18:46:05 +00:00
|
|
|
import android.os.Handler;
|
2013-05-30 04:31:43 +00:00
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.view.SurfaceHolder;
|
|
|
|
import android.view.SurfaceView;
|
|
|
|
|
2013-11-06 22:56:23 +00:00
|
|
|
import java.util.ArrayList;
|
|
|
|
import java.util.Collections;
|
|
|
|
import java.util.List;
|
|
|
|
|
2013-05-30 04:31:43 +00:00
|
|
|
public class GeckoView extends LayerView
|
|
|
|
implements GeckoEventListener, ContextGetter {
|
|
|
|
|
2013-08-23 18:46:05 +00:00
|
|
|
private static final String LOGTAG = "GeckoView";
|
|
|
|
|
2013-05-30 04:31:43 +00:00
|
|
|
public GeckoView(Context context, AttributeSet attrs) {
|
|
|
|
super(context, attrs);
|
|
|
|
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.GeckoView);
|
|
|
|
String url = a.getString(R.styleable.GeckoView_url);
|
2013-08-02 20:46:07 +00:00
|
|
|
boolean doInit = a.getBoolean(R.styleable.GeckoView_doinit, true);
|
2013-05-30 04:31:43 +00:00
|
|
|
a.recycle();
|
|
|
|
|
2013-08-02 20:46:07 +00:00
|
|
|
if (!doInit)
|
|
|
|
return;
|
|
|
|
|
2013-08-20 21:54:16 +00:00
|
|
|
// If running outside of a GeckoActivity (eg, from a library project),
|
|
|
|
// load the native code and disable content providers
|
2013-10-23 16:33:56 +00:00
|
|
|
boolean isGeckoActivity = false;
|
|
|
|
try {
|
|
|
|
isGeckoActivity = context instanceof GeckoActivity;
|
|
|
|
} catch (NoClassDefFoundError ex) {}
|
|
|
|
|
|
|
|
if (!isGeckoActivity) {
|
2013-08-23 18:46:05 +00:00
|
|
|
// Set the GeckoInterface if the context is an activity and the GeckoInterface
|
|
|
|
// has not already been set
|
|
|
|
if (context instanceof Activity && getGeckoInterface() == null) {
|
|
|
|
setGeckoInterface(new BaseGeckoInterface(context));
|
|
|
|
}
|
|
|
|
|
|
|
|
Clipboard.init(context);
|
2013-09-05 04:33:11 +00:00
|
|
|
HardwareUtils.init(context);
|
2013-10-16 21:02:36 +00:00
|
|
|
GeckoNetworkManager.getInstance().init(context);
|
2013-09-05 04:33:11 +00:00
|
|
|
|
2013-08-23 18:46:05 +00:00
|
|
|
GeckoLoader.loadMozGlue();
|
2013-08-20 21:54:16 +00:00
|
|
|
BrowserDB.setEnableContentProviders(false);
|
2013-10-23 16:33:56 +00:00
|
|
|
}
|
2013-08-20 21:54:16 +00:00
|
|
|
|
2013-08-08 13:02:02 +00:00
|
|
|
if (url != null) {
|
|
|
|
GeckoThread.setUri(url);
|
|
|
|
GeckoThread.setAction(Intent.ACTION_VIEW);
|
2013-05-30 04:31:43 +00:00
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createURILoadEvent(url));
|
|
|
|
}
|
|
|
|
GeckoAppShell.setContextGetter(this);
|
|
|
|
if (context instanceof Activity) {
|
|
|
|
Tabs tabs = Tabs.getInstance();
|
2013-07-15 19:12:15 +00:00
|
|
|
tabs.attachToContext(context);
|
2013-05-30 04:31:43 +00:00
|
|
|
}
|
|
|
|
GeckoAppShell.registerEventListener("Gecko:Ready", this);
|
|
|
|
|
|
|
|
ThreadUtils.setUiThread(Thread.currentThread(), new Handler());
|
|
|
|
initializeView(GeckoAppShell.getEventDispatcher());
|
2013-08-02 20:46:07 +00:00
|
|
|
|
2013-10-16 21:02:39 +00:00
|
|
|
GeckoProfile profile = GeckoProfile.get(context).forceCreate();
|
2013-08-02 20:46:07 +00:00
|
|
|
BrowserDB.initialize(profile.getName());
|
|
|
|
|
2013-05-30 04:31:43 +00:00
|
|
|
if (GeckoThread.checkAndSetLaunchState(GeckoThread.LaunchState.Launching, GeckoThread.LaunchState.Launched)) {
|
|
|
|
GeckoAppShell.setLayerView(this);
|
2013-08-08 13:02:02 +00:00
|
|
|
GeckoThread.createAndStart();
|
2013-05-30 04:31:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-06 22:56:23 +00:00
|
|
|
/**
|
|
|
|
* Add a Browser to the GeckoView container.
|
|
|
|
* @param url The URL resource to load into the new Browser.
|
|
|
|
*/
|
|
|
|
public Browser addBrowser(String url) {
|
|
|
|
Tab tab = Tabs.getInstance().loadUrl(url, Tabs.LOADURL_NEW_TAB);
|
|
|
|
if (tab != null) {
|
|
|
|
return new Browser(tab.getId());
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Remove a Browser from the GeckoView container.
|
|
|
|
* @param browser The Browser to remove.
|
|
|
|
*/
|
|
|
|
public void removeBrowser(Browser browser) {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(browser.getId());
|
|
|
|
if (tab != null) {
|
|
|
|
Tabs.getInstance().closeTab(tab);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the active/visible Browser.
|
|
|
|
* @param browser The Browser to make selected.
|
|
|
|
*/
|
|
|
|
public void setCurrentBrowser(Browser browser) {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(browser.getId());
|
|
|
|
if (tab != null) {
|
|
|
|
Tabs.getInstance().selectTab(tab.getId());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the active/visible Browser.
|
|
|
|
* @return The current selected Browser.
|
|
|
|
*/
|
|
|
|
public Browser getCurrentBrowser() {
|
|
|
|
Tab tab = Tabs.getInstance().getSelectedTab();
|
|
|
|
if (tab != null) {
|
|
|
|
return new Browser(tab.getId());
|
|
|
|
}
|
|
|
|
return null;
|
2013-05-30 04:31:43 +00:00
|
|
|
}
|
|
|
|
|
2013-11-06 22:56:23 +00:00
|
|
|
/**
|
|
|
|
* Get the list of current Browsers in the GeckoView container.
|
|
|
|
* @return An unmodifiable List of Browser objects.
|
|
|
|
*/
|
|
|
|
public List<Browser> getBrowsers() {
|
|
|
|
ArrayList<Browser> browsers = new ArrayList<Browser>();
|
|
|
|
Iterable<Tab> tabs = Tabs.getInstance().getTabsInOrder();
|
|
|
|
for (Tab tab : tabs) {
|
|
|
|
browsers.add(new Browser(tab.getId()));
|
|
|
|
}
|
|
|
|
return Collections.unmodifiableList(browsers);
|
|
|
|
}
|
2013-08-13 20:43:00 +00:00
|
|
|
|
2013-11-06 22:56:23 +00:00
|
|
|
/**
|
|
|
|
* Not part of the public API. Ignore.
|
|
|
|
*/
|
2013-05-30 04:31:43 +00:00
|
|
|
public void handleMessage(String event, JSONObject message) {
|
|
|
|
if (event.equals("Gecko:Ready")) {
|
|
|
|
GeckoThread.setLaunchState(GeckoThread.LaunchState.GeckoRunning);
|
|
|
|
Tab selectedTab = Tabs.getInstance().getSelectedTab();
|
|
|
|
if (selectedTab != null)
|
|
|
|
Tabs.getInstance().notifyListeners(selectedTab, Tabs.TabEvents.SELECTED);
|
|
|
|
geckoConnected();
|
|
|
|
GeckoAppShell.setLayerClient(getLayerClient());
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Viewport:Flush", null));
|
|
|
|
show();
|
|
|
|
requestRender();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-23 18:46:05 +00:00
|
|
|
public static void setGeckoInterface(final BaseGeckoInterface geckoInterface) {
|
|
|
|
GeckoAppShell.setGeckoInterface(geckoInterface);
|
|
|
|
}
|
|
|
|
|
|
|
|
public static GeckoAppShell.GeckoInterface getGeckoInterface() {
|
|
|
|
return GeckoAppShell.getGeckoInterface();
|
2013-05-30 04:31:43 +00:00
|
|
|
}
|
2013-11-06 22:56:23 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Wrapper for a browser in the GeckoView container. Associated with a browser
|
|
|
|
* element in the Gecko system.
|
|
|
|
*/
|
|
|
|
public class Browser {
|
|
|
|
private final int mId;
|
|
|
|
private Browser(int Id) {
|
|
|
|
mId = Id;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the ID of the Browser. This is the same ID used by Gecko for it's underlying
|
|
|
|
* browser element.
|
|
|
|
* @return The integer ID of the Browser.
|
|
|
|
*/
|
|
|
|
private int getId() {
|
|
|
|
return mId;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Load a URL resource into the Browser.
|
|
|
|
* @param url The URL string.
|
|
|
|
*/
|
|
|
|
public void loadUrl(String url) {
|
|
|
|
JSONObject args = new JSONObject();
|
|
|
|
try {
|
|
|
|
args.put("url", url);
|
|
|
|
args.put("parentId", -1);
|
|
|
|
args.put("newTab", false);
|
|
|
|
args.put("tabID", mId);
|
|
|
|
} catch (Exception e) {
|
|
|
|
Log.w(LOGTAG, "Error building JSON arguments for loadUrl.", e);
|
|
|
|
}
|
|
|
|
GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("Tab:Load", args.toString()));
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Reload the current URL resource into the Browser. The URL is force loaded from the
|
|
|
|
* network and is not pulled from cache.
|
|
|
|
*/
|
|
|
|
public void reload() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
tab.doReload();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop the current loading operation.
|
|
|
|
*/
|
|
|
|
public void stop() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
tab.doStop();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check to see if the Browser has session history and can go back to a
|
|
|
|
* previous page.
|
|
|
|
* @return A boolean flag indicating if previous session exists.
|
|
|
|
* This method will likely be removed and replaced by a callback in GeckoViewContent
|
|
|
|
*/
|
|
|
|
public boolean canGoBack() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
return tab.canDoBack();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move backward in the session history, if that's possible.
|
|
|
|
*/
|
|
|
|
public void goBack() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
tab.doBack();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check to see if the Browser has session history and can go forward to a
|
|
|
|
* new page.
|
|
|
|
* @return A boolean flag indicating if forward session exists.
|
|
|
|
* This method will likely be removed and replaced by a callback in GeckoViewContent
|
|
|
|
*/
|
|
|
|
public boolean canGoForward() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
return tab.canDoForward();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Move forward in the session history, if that's possible.
|
|
|
|
*/
|
|
|
|
public void goForward() {
|
|
|
|
Tab tab = Tabs.getInstance().getTab(mId);
|
|
|
|
if (tab != null) {
|
|
|
|
tab.doForward();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-05-30 04:31:43 +00:00
|
|
|
}
|