// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package org.chromium.sdk.internal.shellprotocol;
import java.io.IOException;
import org.chromium.sdk.Browser;
import org.chromium.sdk.BrowserTab;
import org.chromium.sdk.DebugEventListener;
import org.chromium.sdk.TabDebugEventListener;
import org.chromium.sdk.internal.shellprotocol.tools.ToolHandler;
import org.chromium.sdk.internal.shellprotocol.tools.ToolName;
import org.chromium.sdk.internal.shellprotocol.tools.ToolOutput;
import org.chromium.sdk.internal.shellprotocol.tools.protocol.input.Result;
import org.chromium.sdk.internal.shellprotocol.tools.protocol.output.MessageFactory;
import org.chromium.sdk.internal.shellprotocol.tools.v8debugger.ChromeDevToolSessionManager;
import org.chromium.sdk.internal.shellprotocol.tools.v8debugger.ChromeDevToolSessionManager.AttachmentFailureException;
import org.chromium.sdk.internal.transport.Connection;
import org.chromium.sdk.internal.transport.Message;
import org.chromium.sdk.internal.v8native.DebugSession;
import org.chromium.sdk.internal.v8native.JavascriptVmImpl;
import org.chromium.sdk.util.MethodIsBlockingException;
/**
* A default, thread-safe implementation of the BrowserTab interface.
*/
public class BrowserTabImpl extends JavascriptVmImpl implements BrowserTab {
/** Tab ID as reported by the DevTools server. */
private final int tabId;
/** The primary tab URL. */
private volatile String url;
private final SessionManager.Ticket<BrowserImpl.Session> connectionTicket;
private final ChromeDevToolSessionManager devToolSessionManager;
/** The listener to report debug events to. */
private DebugEventListener debugEventListener = null;
/** The listener to report browser-related debug events to. */
private TabDebugEventListener tabDebugEventListener = null;
public BrowserTabImpl(int tabId, Connection connection,
SessionManager.Ticket<BrowserImpl.Session> ticket) throws IOException {
this.tabId = tabId;
this.connectionTicket = ticket;
String tabIdString = String.valueOf(tabId);
ChromeDevToolOutput chromeDevToolOutput = new ChromeDevToolOutput(tabIdString, connection);
this.devToolSessionManager = new ChromeDevToolSessionManager(this, chromeDevToolOutput);
ToolHandler toolHandler = devToolSessionManager.getToolHandler();
// After this statement we are responsible for dismissing our ticket (we do it via eos message).
getBrowserConnectionSession().registerTab(tabId, toolHandler,
this.devToolSessionManager.getDebugSession());
}
public String getUrl() {
return url;
}
public void setUrl(String newUrl) {
url = newUrl;
}
public int getId() {
return tabId;
}
@Override
public DebugSession getDebugSession() {
return devToolSessionManager.getDebugSession();
}
public synchronized TabDebugEventListener getTabDebugEventListener() {
return tabDebugEventListener;
}
public Browser getBrowser() {
return getBrowserConnectionSession().getBrowser();
}
public BrowserImpl.Session getBrowserConnectionSession() {
return connectionTicket.getSession();
}
synchronized void attach(TabDebugEventListener listener)
throws IOException, MethodIsBlockingException {
this.tabDebugEventListener = listener;
this.debugEventListener = listener.getDebugEventListener();
boolean normalExit = false;
try {
Result result;
try {
result = devToolSessionManager.attachToTab();
} catch (AttachmentFailureException e) {
throw newIOException(null, e);
}
if (Result.OK != result) {
throw new IOException("Failed to attach with result: " + result);
}
normalExit = true;
} finally {
if (!normalExit) {
devToolSessionManager.cutTheLineMyself();
}
}
}
public boolean detach() {
Result result = devToolSessionManager.detachFromTab();
return Result.OK == result;
}
public boolean isAttached() {
return devToolSessionManager.isAttachedForUi();
}
public void sessionTerminated() {
//browserSession.sessionTerminated(this.tabId);
}
public ToolHandler getV8ToolHandler() {
return devToolSessionManager.getToolHandler();
}
public ChromeDevToolSessionManager getSessionManager() {
return devToolSessionManager;
}
public void handleEosFromToolService() {
getBrowserConnectionSession().unregisterTab(tabId);
connectionTicket.dismiss();
}
private static class ChromeDevToolOutput implements ToolOutput {
private final String destination;
private final Connection connection;
ChromeDevToolOutput(String destination, Connection connection) {
this.destination = destination;
this.connection = connection;
}
public void send(String content) {
Message message =
MessageFactory.createMessage(ToolName.V8_DEBUGGER.value, destination, content);
connection.send(message);
}
public void runInDispatchThread(Runnable callback) {
connection.runInDispatchThread(callback);
}
}
public DebugEventListener getDebugEventListener() {
return debugEventListener;
}
}