From ca9f698bac3a5ae9af42d420cfff2f5f1736232f Mon Sep 17 00:00:00 2001 From: mnaganov Date: Fri, 15 May 2015 12:28:17 -0700 Subject: Remove devtools_bridge component The component was experimental and uses org.apache.http library, which is now deprecated in Android. BUG=488202 TBR=erikwright@chromium.org Review URL: https://codereview.chromium.org/1142463003 Cr-Commit-Position: refs/heads/master@{#330163} --- components/devtools_bridge/android/DEPS | 3 - .../android/apiary_client_factory.cc | 41 -- .../android/apiary_client_factory.h | 26 -- .../devtools_bridge/AbstractDataChannel.java | 77 ---- .../devtools_bridge/AbstractPeerConnection.java | 106 ----- .../devtools_bridge/DevToolsBridgeServer.java | 181 --------- .../devtools_bridge/DevToolsBridgeServiceBase.java | 151 ------- .../devtools_bridge/GCDNotificationHandler.java | 177 --------- .../devtools_bridge/RTCConfiguration.java | 62 --- .../components/devtools_bridge/ServerSession.java | 178 --------- .../devtools_bridge/ServiceLifetimeManager.java | 83 ---- .../components/devtools_bridge/SessionBase.java | 435 --------------------- .../devtools_bridge/SessionControlMessages.java | 251 ------------ .../devtools_bridge/SessionDependencyFactory.java | 44 --- .../SessionDependencyFactoryNative.java | 283 -------------- .../devtools_bridge/SignalingReceiver.java | 44 --- .../components/devtools_bridge/SocketTunnel.java | 27 -- .../apiary/ApiaryClientFactory.java | 61 --- .../apiary/BlockingGCMRegistrar.java | 82 ---- .../devtools_bridge/apiary/GCDClient.java | 193 --------- .../apiary/JsonResponseHandler.java | 70 ---- .../devtools_bridge/apiary/OAuthClient.java | 102 ----- .../devtools_bridge/apiary/OAuthResult.java | 28 -- .../devtools_bridge/commands/Command.java | 84 ---- .../commands/CommandDefinition.java | 40 -- .../commands/CommandFormatException.java | 18 - .../devtools_bridge/commands/CommandReceiver.java | 97 ----- .../devtools_bridge/commands/Commands.java | 196 ---------- .../devtools_bridge/commands/ParamDefinition.java | 49 --- .../devtools_bridge/commands/ParamDefinitions.java | 203 ---------- .../devtools_bridge/gcd/InstanceCredential.java | 49 --- .../devtools_bridge/gcd/InstanceDescription.java | 55 --- .../devtools_bridge/gcd/MessageReader.java | 181 --------- .../devtools_bridge/gcd/MessageWriter.java | 156 -------- .../devtools_bridge/gcd/Notification.java | 63 --- .../ui/GCDRegistrationFragment.java | 320 --------------- .../devtools_bridge/util/LooperExecutor.java | 56 --- .../android/javatests/AndroidManifest.xml | 74 ---- .../devtools_bridge/DevToolsBridgeServerTest.java | 93 ----- .../devtools_bridge/LocalSessionBridgeTest.java | 114 ------ .../SessionControlMessagesTest.java | 94 ----- .../SessionDependencyFactoryTest.java | 200 ---------- .../devtools_bridge/SocketTunnelServerTest.java | 234 ----------- .../apiary/JsonResponseHandlerTest.java | 138 ------- .../devtools_bridge/apiary/OAuthClientTest.java | 39 -- .../commands/CommandReceiverTest.java | 91 ----- .../commands/CommandSenderTest.java | 126 ------ .../devtools_bridge/commands/CommandsTest.java | 124 ------ .../commands/ParamDefinitionsTest.java | 81 ---- .../devtools_bridge/gcd/MessageReaderTest.java | 119 ------ .../devtools_bridge/tests/DebugActivity.java | 136 ------- .../devtools_bridge/tests/DebugService.java | 243 ------------ .../devtools_bridge/tests/TestApplication.java | 28 -- .../android/session_dependency_factory_android.cc | 302 -------------- .../android/session_dependency_factory_android.h | 37 -- 55 files changed, 6545 deletions(-) delete mode 100644 components/devtools_bridge/android/DEPS delete mode 100644 components/devtools_bridge/android/apiary_client_factory.cc delete mode 100644 components/devtools_bridge/android/apiary_client_factory.h delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractDataChannel.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractPeerConnection.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServer.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServiceBase.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/GCDNotificationHandler.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/RTCConfiguration.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServerSession.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServiceLifetimeManager.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionBase.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionControlMessages.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryNative.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SignalingReceiver.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SocketTunnel.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/ApiaryClientFactory.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/BlockingGCMRegistrar.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/GCDClient.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandler.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthClient.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthResult.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Command.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandDefinition.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandFormatException.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandReceiver.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Commands.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinition.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinitions.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceCredential.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceDescription.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageReader.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageWriter.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/Notification.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java delete mode 100644 components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/util/LooperExecutor.java delete mode 100644 components/devtools_bridge/android/javatests/AndroidManifest.xml delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/DevToolsBridgeServerTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/LocalSessionBridgeTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionControlMessagesTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandlerTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/OAuthClientTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandReceiverTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandSenderTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandsTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/ParamDefinitionsTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/gcd/MessageReaderTest.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugActivity.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugService.java delete mode 100644 components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/TestApplication.java delete mode 100644 components/devtools_bridge/android/session_dependency_factory_android.cc delete mode 100644 components/devtools_bridge/android/session_dependency_factory_android.h (limited to 'components/devtools_bridge/android') diff --git a/components/devtools_bridge/android/DEPS b/components/devtools_bridge/android/DEPS deleted file mode 100644 index c80012b5..0000000 --- a/components/devtools_bridge/android/DEPS +++ /dev/null @@ -1,3 +0,0 @@ -include_rules = [ - "+jni", -] diff --git a/components/devtools_bridge/android/apiary_client_factory.cc b/components/devtools_bridge/android/apiary_client_factory.cc deleted file mode 100644 index 2224643..0000000 --- a/components/devtools_bridge/android/apiary_client_factory.cc +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2014 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. - -#include "components/devtools_bridge/android/apiary_client_factory.h" - -#include "base/android/jni_string.h" -#include "google_apis/google_api_keys.h" -#include "jni/ApiaryClientFactory_jni.h" - -using base::android::ConvertUTF8ToJavaString; - -namespace devtools_bridge { -namespace android { - -// static -bool ApiaryClientFactory::RegisterNatives(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -// static -jstring GetAPIKey(JNIEnv* env, jobject jcaller) { - return ConvertUTF8ToJavaString(env, google_apis::GetAPIKey()).Release(); -} - -// static -jstring GetOAuthClientId(JNIEnv* env, jobject jcaller) { - return ConvertUTF8ToJavaString( - env, google_apis::GetOAuth2ClientID( - google_apis::OAuth2Client::CLIENT_MAIN)).Release(); -} - -// static -jstring GetOAuthClientSecret(JNIEnv* env, jobject jcaller) { - return ConvertUTF8ToJavaString( - env, google_apis::GetOAuth2ClientSecret( - google_apis::OAuth2Client::CLIENT_MAIN)).Release(); -} - -} // namespace android -} // namespace devtools_bridge diff --git a/components/devtools_bridge/android/apiary_client_factory.h b/components/devtools_bridge/android/apiary_client_factory.h deleted file mode 100644 index d44909c..0000000 --- a/components/devtools_bridge/android/apiary_client_factory.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2014 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. - -#ifndef COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_APIARY_CLIENT_FACTORY_H_ -#define COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_APIARY_CLIENT_FACTORY_H_ - -#include - -namespace devtools_bridge { -namespace android { - -/** - * Native counterpart of Java |ApiaryClientFactory| in DevTools Bridge. - * Provides access to API keys and OAuth credentials needed for GCD - * robotic account. - */ -class ApiaryClientFactory { - public: - static bool RegisterNatives(JNIEnv* env); -}; - -} // namespace android -} // namespace devtools_bridge - -#endif // COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_APIARY_CLIENT_FACTORY_H_ diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractDataChannel.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractDataChannel.java deleted file mode 100644 index e92c6db..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractDataChannel.java +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import java.nio.ByteBuffer; - -/** - * Limited view on org.webrtc.DataChannel. Abstraction layer helps with: - * 1. Mocking in tests. There is no need to emulate full set of features of the DataChannel. - * 2. Allows both native and Java API implementation for WebRTC data channel. - * 3. Hides unused features. - * Only SCTP data channels supported. - * Data channel is thread safe (except the dispose method). - */ -public abstract class AbstractDataChannel { - /** - * Observer's callbacks are called on WebRTC signaling thread (or it's equivalent in tests). - */ - public interface Observer { - void onStateChange(State state); - - /** - * TEXT and BINARY messages should be handled equally. Size of the message is - * |message|.remaining(). |message| may reference to a native buffer on stack so - * the reference to the buffer must not outlive the invocation. - */ - void onMessage(ByteBuffer message); - } - - /** - * Type is only significant for JavaScript-based counterpart. TEXT messages will - * be observed as strings, BINARY as ByteArray's. - */ - public enum MessageType { - TEXT, BINARY - } - - /** - * State of the data channel. - * Only 2 states of channel are important here: OPEN and everything else. - */ - public enum State { - OPEN, CLOSED - } - - /** - * Registers an observer. - */ - public abstract void registerObserver(Observer observer); - - /** - * Unregisters the previously registered observer. - * Observer unregistration synchronized with signaling thread. If some data modified - * in observer callbacks without additional synchronization it's safe to access - * this data on the current thread after calling this method. - */ - public abstract void unregisterObserver(); - - /** - * Sending message to the data channel. - * Message size is |message|.remaining(). - */ - public abstract void send(ByteBuffer message, MessageType type); - - /** - * Closing data channel. Both channels in the pair will change state to CLOSED. - */ - public abstract void close(); - - /** - * Releases native objects (if any). Closes data channel. No other methods are allowed after it - * (in multithread scenario needs synchronization with access to the data channel). - */ - public abstract void dispose(); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractPeerConnection.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractPeerConnection.java deleted file mode 100644 index 3e1fb6a..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/AbstractPeerConnection.java +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -/** - * Limited view on org.webrtc.PeerConnection. Abstraction layer helps with: - * 1. Allows both native and Java API implementation. - * 2. Hides unused features. - * Should be accessed on a single thread. - */ -public abstract class AbstractPeerConnection { - /** - * All methods are callen on WebRTC signaling thread. - */ - public interface Observer { - /** - * Called when createAndSetLocalDescription or setRemoteDescription failed. - */ - void onFailure(String description); - - /** - * Called when createAndSetLocalDescription succeeded. - */ - void onLocalDescriptionCreatedAndSet(SessionDescriptionType type, String description); - - /** - * Called when setRemoteDescription succeeded. - */ - void onRemoteDescriptionSet(); - - /** - * New ICE candidate available. String representation defined in the IceCandidate class. - * To be sent to the remote peer connection. - */ - void onIceCandidate(String iceCandidate); - - /** - * Called when connected or disconnected. In disconnected state recovery procedure - * should only rely on signaling channel. - */ - void onIceConnectionChange(boolean connected); - } - - /** - * Type of session description. - */ - public enum SessionDescriptionType { - OFFER, ANSWER - } - - /** - * The result of this method will be invocation onLocalDescriptionCreatedAndSet - * or onFailure on the observer. Should not be called when waiting result of - * setRemoteDescription. - */ - public abstract void createAndSetLocalDescription(SessionDescriptionType type); - - /** - * Result of this method will be invocation onRemoteDescriptionSet or onFailure on the observer. - */ - public abstract void setRemoteDescription(SessionDescriptionType type, String description); - - /** - * Adds a remote ICE candidate. - */ - public abstract void addIceCandidate(String candidate); - - /** - * Destroys native objects. Synchronized with the signaling thread - * (no observer method called when the connection disposed) - */ - public abstract void dispose(); - - /** - * Creates prenegotiated SCTP data channel. - */ - public abstract AbstractDataChannel createDataChannel(int channelId); - - /** - * Helper class which enforces string representation of an ICE candidate. - */ - static class IceCandidate { - public final String sdpMid; - public final int sdpMLineIndex; - public final String sdp; - - public IceCandidate(String sdpMid, int sdpMLineIndex, String sdp) { - this.sdpMid = sdpMid; - this.sdpMLineIndex = sdpMLineIndex; - this.sdp = sdp; - } - - public String toString() { - return sdpMid + ":" + sdpMLineIndex + ":" + sdp; - } - - public static IceCandidate fromString(String candidate) throws IllegalArgumentException { - String[] parts = candidate.split(":", 3); - if (parts.length != 3) - throw new IllegalArgumentException("Expected column separated list."); - return new IceCandidate(parts[0], Integer.parseInt(parts[1]), parts[2]); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServer.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServer.java deleted file mode 100644 index 076fe50..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServer.java +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.content.Context; -import android.content.Intent; -import android.content.SharedPreferences; - -import org.chromium.components.devtools_bridge.util.LooperExecutor; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Responsibility of DevToolsBridgeServer consists of handling commands and managing sessions. - * It designed to live in DevToolsBridgeServiceBase but also may live separately (in tests). - */ -public class DevToolsBridgeServer implements SignalingReceiver { - private final LooperExecutor mExecutor; - private final SessionDependencyFactory mFactory = SessionDependencyFactory.newInstance(); - private final Map mSessions = new HashMap(); - private final GCDNotificationHandler mHandler; - private final Delegate mDelegate; - - /** - * Callback for finding DevTools socket asynchronously. Needed in multiprocess - * scenario when socket name is variable. May be called synchronously. - */ - public interface QuerySocketCallback { - void onSuccess(String socketName); - void onFailure(); - } - - /** - * Delegate abstracts Server from service lifetime management and UI. - */ - public interface Delegate { - Context getContext(); - - // When runs in a service this service should not die when |sessionCount| > 0. - void onSessionCountChange(int sessionCount); - - // Lets query a socket name when starting a new session. Result may change - // (in multiprocess scenario: when browser process stops and then starts again). - void querySocketName(QuerySocketCallback callback); - } - - public DevToolsBridgeServer(Delegate delegate) { - assert delegate != null; - - mExecutor = LooperExecutor.newInstanceForMainLooper(delegate.getContext()); - mHandler = new GCDNotificationHandler(this); - mDelegate = delegate; - } - - private void checkCalledOnHostServiceThread() { - assert mExecutor.isCalledOnSessionThread(); - } - - public Context getContext() { - return mDelegate.getContext(); - } - - public SharedPreferences getPreferences() { - return getPreferences(getContext()); - } - - public static SharedPreferences getPreferences(Context context) { - return context.getSharedPreferences( - DevToolsBridgeServer.class.getName(), Context.MODE_PRIVATE); - } - - public void handleCloudMessage(Intent cloudMessage, Runnable completionHandler) { - if (mHandler.isNotification(cloudMessage)) { - mHandler.onNotification(cloudMessage, completionHandler); - } else { - completionHandler.run(); - } - } - - public void updateCloudMessagesId(String channelId, Runnable completionHandler) { - mHandler.updateCloudMessagesId(channelId, completionHandler); - } - - /** - * Should be called in service's onDestroy. - */ - public void dispose() { - checkCalledOnHostServiceThread(); - - for (ServerSession session : mSessions.values()) { - session.dispose(); - } - mFactory.dispose(); - mHandler.dispose(); - } - - @Override - public void startSession( - final String sessionId, - final RTCConfiguration config, - final String offer, - final SessionBase.NegotiationCallback callback) { - checkCalledOnHostServiceThread(); - if (mSessions.containsKey(sessionId)) { - callback.onFailure("Session " + sessionId + " already exists"); - return; - } - - mDelegate.querySocketName(new QuerySocketCallback() { - @Override - public void onSuccess(String socketName) { - ServerSession session = new ServerSession(mFactory, mExecutor, socketName); - session.setEventListener(new SessionEventListener(sessionId)); - mSessions.put(sessionId, session); - session.startSession(config, offer, callback); - mDelegate.onSessionCountChange(mSessions.size()); - } - - @Override - public void onFailure() { - callback.onFailure("Socket not available"); - } - }); - } - - @Override - public void renegotiate( - String sessionId, - String offer, - SessionBase.NegotiationCallback callback) { - checkCalledOnHostServiceThread(); - if (!mSessions.containsKey(sessionId)) { - callback.onFailure("Session does not exist"); - return; - } - ServerSession session = mSessions.get(sessionId); - session.renegotiate(offer, callback); - } - - @Override - public void iceExchange( - String sessionId, - List clientCandidates, - SessionBase.IceExchangeCallback callback) { - checkCalledOnHostServiceThread(); - if (!mSessions.containsKey(sessionId)) { - callback.onFailure("Session does not exist"); - return; - } - ServerSession session = mSessions.get(sessionId); - session.iceExchange(clientCandidates, callback); - } - - private class SessionEventListener implements SessionBase.EventListener { - private final String mSessionId; - - public SessionEventListener(String sessionId) { - mSessionId = sessionId; - } - - public void onCloseSelf() { - checkCalledOnHostServiceThread(); - - mSessions.remove(mSessionId); - mDelegate.onSessionCountChange(mSessions.size()); - } - } - - public void closeAllSessions() { - if (mSessions.isEmpty()) return; - for (ServerSession session : mSessions.values()) { - session.stop(); - } - mSessions.clear(); - mDelegate.onSessionCountChange(mSessions.size()); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServiceBase.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServiceBase.java deleted file mode 100644 index f893592..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/DevToolsBridgeServiceBase.java +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.app.Service; -import android.content.Context; -import android.content.Intent; -import android.os.IBinder; -import android.os.Looper; -import android.support.v4.content.WakefulBroadcastReceiver; - -import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener; - -/** - * Base class for a service which hosts DevToolsBridgeServer. It relies on Cloud Messages - * intents rebroadcasted via MultiplexingGcmListener. It intentionally doesn't inherit from - * MultiplexingGcmListener.AbstractListener because this service may not be IntentService - * due to lifetime management restrictions of it. - * - * Service lives while any intent being processed or any client connected. - * TODO(serya): Service lifetime management code should be moved here from DevToolsBridgeServer. - */ -public abstract class DevToolsBridgeServiceBase extends Service { - private static final String WAKELOCK_KEY = "DevToolsBridgeService.WAKELOCK"; - - /** - * Delivers intents from MultiplexingGcmListener to the service making sure - * wakelock is kept during the process. - */ - protected abstract static class ReceiverBase extends WakefulBroadcastReceiver { - private final Class mConcreteServiceClass; - - protected ReceiverBase(Class concreteServiceClass) { - mConcreteServiceClass = concreteServiceClass; - } - - @Override - public void onReceive(Context context, Intent intent) { - // Pass all intent extras to the service. - Intent startIntent = new Intent(context, mConcreteServiceClass); - startIntent.setAction(intent.getAction()); - if (intent.getExtras() != null) startIntent.putExtras(intent.getExtras()); - startWakefulService(context, startIntent); - } - } - - private DevToolsBridgeServer mServer; - private ServiceLifetimeManager mLifetimeManager; - - private Runnable mSessionHandlingTask; - - @Override - public IBinder onBind(Intent intent) { - return null; - } - - @Override - public void onCreate() { - super.onCreate(); - mServer = new DevToolsBridgeServer(new ServerDelegate()); - mLifetimeManager = new ServiceLifetimeManager(this, WAKELOCK_KEY); - } - - @Override - public void onDestroy() { - mServer.dispose(); - - super.onDestroy(); - } - - @Override - public final int onStartCommand(Intent intent, int flags, int startId) { - Runnable intentHandlingTask = mLifetimeManager.startTask(startId); - if (MultiplexingGcmListener.Intents.ACTION.equals(intent.getAction())) { - handleGCMIntent(intent); - } else { - onHandleIntent(intent); - } - ReceiverBase.completeWakefulIntent(intent); - intentHandlingTask.run(); // Stops self if no other task started. - return START_NOT_STICKY; - } - - private void handleGCMIntent(Intent intent) { - if (intent.getBooleanExtra(MultiplexingGcmListener.Intents.EXTRA_OP_MESSAGE, false)) { - mServer.handleCloudMessage(intent, mLifetimeManager.startTask()); - } else if (intent.getBooleanExtra( - MultiplexingGcmListener.Intents.EXTRA_OP_REGISTERED, false)) { - mServer.updateCloudMessagesId( - intent.getStringExtra(MultiplexingGcmListener.Intents.EXTRA_DATA_REG_ID), - startTask()); - } else if (intent.getBooleanExtra( - MultiplexingGcmListener.Intents.EXTRA_OP_UNREGISTERED, false)) { - mServer.updateCloudMessagesId("", startTask()); - } - } - - /** - * Unlike similar method in IntentService this one runs on service thread. - * Cloud Messages intents are handled separately. - */ - protected void onHandleIntent(Intent intent) { - assert calledOnServiceThread(); - } - - protected abstract void querySocketName(DevToolsBridgeServer.QuerySocketCallback callback); - protected abstract void onFirstSessionStarted(); - protected abstract void onLastSessionStopped(); - protected void onSessionCountChange(int sessionCount) {} - - protected DevToolsBridgeServer server() { - return mServer; - } - - protected Runnable startTask() { - return mLifetimeManager.startTask(); - } - - protected boolean calledOnServiceThread() { - return Looper.myLooper() == getMainLooper(); - } - - private class ServerDelegate implements DevToolsBridgeServer.Delegate { - @Override - public Context getContext() { - return DevToolsBridgeServiceBase.this; - } - - @Override - public void onSessionCountChange(int sessionCount) { - assert calledOnServiceThread(); - if (sessionCount > 0 && mSessionHandlingTask == null) { - mSessionHandlingTask = startTask(); - DevToolsBridgeServiceBase.this.onFirstSessionStarted(); - } else if (sessionCount == 0 && mSessionHandlingTask != null) { - mSessionHandlingTask.run(); - mSessionHandlingTask = null; - DevToolsBridgeServiceBase.this.onLastSessionStopped(); - } else { - DevToolsBridgeServiceBase.this.onSessionCountChange(sessionCount); - } - } - - @Override - public void querySocketName(DevToolsBridgeServer.QuerySocketCallback callback) { - DevToolsBridgeServiceBase.this.querySocketName(callback); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/GCDNotificationHandler.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/GCDNotificationHandler.java deleted file mode 100644 index fdf5de9..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/GCDNotificationHandler.java +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.content.Intent; -import android.content.SharedPreferences; -import android.util.Log; - -import org.chromium.components.devtools_bridge.apiary.ApiaryClientFactory; -import org.chromium.components.devtools_bridge.apiary.OAuthResult; -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.commands.CommandReceiver; -import org.chromium.components.devtools_bridge.gcd.InstanceCredential; -import org.chromium.components.devtools_bridge.gcd.Notification; - -import java.io.IOException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; - -/** - * Handles notifications from GCD. For command notification it delegates work to - * DevToolsBridgeServer and updates command state when it finish. for unregistration - * notification it updates preferences. - */ -public class GCDNotificationHandler { - private static final String TAG = "GCDNotificationHandler"; - - private static final String EXTRA_FROM = "from"; - private static final String EXTRA_NOTIFICATION = "notification"; - private static final String EXPECTED_SENDER = - "clouddevices-gcm@clouddevices.google.com"; - - private final DevToolsBridgeServer mServer; - private final ApiaryClientFactory mClientFactory; - private final CommandReceiver mCommandReceiver; - - private final ExecutorService mIOExecutor; - private OAuthResult mOAuthResult; - - public GCDNotificationHandler(DevToolsBridgeServer server) { - mServer = server; - mClientFactory = new ApiaryClientFactory(); - mCommandReceiver = new CommandReceiver(server); - mIOExecutor = Executors.newSingleThreadExecutor(); - } - - public void dispose() { - mIOExecutor.shutdown(); - mClientFactory.close(); - } - - public boolean isNotification(Intent intent) { - return EXPECTED_SENDER.equals(intent.getStringExtra(EXTRA_FROM)) - && intent.getStringExtra(EXTRA_NOTIFICATION) != null; - } - - public void onNotification(Intent intent, Runnable completionHandler) { - try { - handle(Notification.read(intent.getStringExtra(EXTRA_NOTIFICATION)), completionHandler); - return; - } catch (Notification.FormatException e) { - Log.e(TAG, "Invalid notification", e); - } - completionHandler.run(); - } - - public void updateCloudMessagesId(final String gcmChannelId, final Runnable completionHandler) { - final InstanceCredential credential = InstanceCredential.get(mServer.getPreferences()); - if (credential == null) return; - - mIOExecutor.submit(new Runnable() { - @Override - public void run() { - try { - mClientFactory.newGCDClient(getAccessToken(credential)) - .patchInstanceGCMChannel(credential.id, gcmChannelId); - } catch (Exception e) { - Log.e(TAG, "Failure when updating GCM channel id", e); - } finally { - completionHandler.run(); - } - } - }); - } - - private void handle(Notification notification, Runnable completionHandler) { - if (notification == null) { - // Unsupported notification type. Ignore. - Log.i(TAG, "Unsupported notification"); - completionHandler.run(); - return; - } - - switch (notification.type) { - case INSTANCE_UNREGISTERED: - onInstanceUnregistered(notification.instanceId, completionHandler); - break; - - case COMMAND_CREATED: - onCommand(notification.instanceId, notification.command, completionHandler); - break; - - default: - completionHandler.run(); - break; - } - } - - private void onInstanceUnregistered(String instanceId, Runnable completionHandler) { - Log.i(TAG, "Received unregistration notification: " + instanceId); - InstanceCredential credential = InstanceCredential.get(mServer.getPreferences()); - if (credential != null && credential.id.equals(instanceId)) { - SharedPreferences.Editor editor = mServer.getPreferences().edit(); - InstanceCredential.remove(editor); - editor.commit(); - } - completionHandler.run(); - } - - private void onCommand(String instanceId, Command command, Runnable completionHandler) { - InstanceCredential credential = InstanceCredential.get(mServer.getPreferences()); - if (credential != null && credential.id.equals(instanceId)) { - mCommandReceiver.receive( - command, new Responder(command, credential, completionHandler)); - } else { - Log.w(TAG, "Ignored command " + command.type + " for " + instanceId); - completionHandler.run(); - } - } - - private String getAccessToken(InstanceCredential credential) throws IOException { - // Called on IO executor. - // TODO(serya): mOAuthResult should be persistent. - if (mOAuthResult == null) { - mOAuthResult = mClientFactory.newOAuthClient().authenticate( - credential.secret); - } - return mOAuthResult.accessToken; - } - - private final class Responder implements Runnable { - private final Command mCommand; - private final InstanceCredential mCredential; - private final Runnable mCompletionHandler; - private boolean mForwardedToIOThread = false; - - public Responder( - Command command, - InstanceCredential credential, - Runnable completionHandler) { - assert command != null; - assert credential != null; - assert completionHandler != null; - - mCommand = command; - mCredential = credential; - mCompletionHandler = completionHandler; - } - - @Override - public void run() { - if (!mForwardedToIOThread) { - mForwardedToIOThread = true; - mIOExecutor.submit(this); - return; - } - try { - mClientFactory.newGCDClient(getAccessToken(mCredential)).patchCommand(mCommand); - } catch (Exception e) { - // TODO(serya): Handle authorization exception. - Log.e(TAG, "Failure when patching command", e); - } - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/RTCConfiguration.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/RTCConfiguration.java deleted file mode 100644 index bb2dbb0..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/RTCConfiguration.java +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * Represents RTCConfiguration (http://www.w3.org/TR/webrtc/#rtcconfiguration-type). - * Replacement for List in Java WebRTC API. - * Transferable through signaling channel. - * Immutable. - */ -public class RTCConfiguration { - /** - * Single ICE server description. - */ - public static class IceServer { - public final String uri; - public final String username; - public final String credential; - - public IceServer(String uri, String username, String credential) { - this.uri = uri; - this.username = username; - this.credential = credential; - } - } - - public final List iceServers; - - private RTCConfiguration(List iceServers) { - this.iceServers = Collections.unmodifiableList(new ArrayList(iceServers)); - } - - public RTCConfiguration() { - this(Collections.emptyList()); - } - - /** - * Builder for RTCConfiguration. - */ - public static class Builder { - private final List mIceServers = new ArrayList(); - - public RTCConfiguration build() { - return new RTCConfiguration(mIceServers); - } - - public Builder addIceServer(String uri, String username, String credential) { - mIceServers.add(new IceServer(uri, username, credential)); - return this; - } - - public Builder addIceServer(String uri) { - return addIceServer(uri, "", ""); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServerSession.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServerSession.java deleted file mode 100644 index 4dadcb9..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServerSession.java +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import java.util.List; - -/** - * DevTools Bridge server session. Handles connection with a ClientSession. - * See SessionBase description for more detais. - */ -public class ServerSession extends SessionBase implements SessionBase.ServerSessionInterface { - private NegotiationCallback mNegotiationCallback; - private IceExchangeCallback mIceExchangeCallback; - private boolean mIceEchangeRequested = false; - - protected int mGatheringDelayMs = 200; - - public ServerSession(SessionDependencyFactory factory, - Executor executor, - String defaultSocketName) { - super(factory, executor, factory.newSocketTunnelServer(defaultSocketName)); - } - - @Override - public void stop() { - super.stop(); - if (mNegotiationCallback != null) { - mNegotiationCallback.onFailure("Session stopped"); - mNegotiationCallback = null; - } - if (mIceExchangeCallback != null) { - mIceExchangeCallback.onFailure("Session stopped"); - mIceExchangeCallback = null; - } - } - - @Override - public void startSession(RTCConfiguration config, - String offer, - NegotiationCallback callback) { - checkCalledOnSessionThread(); - if (isStarted()) { - callback.onFailure("Session already started"); - return; - } - - ClientMessageHandler handler = new ClientMessageHandler(); - start(config, handler); - - negotiate(offer, callback); - } - - @Override - public void renegotiate(String offer, NegotiationCallback callback) { - checkCalledOnSessionThread(); - if (!isStarted()) { - callback.onFailure("Session is not started"); - return; - } - - callback.onFailure("Not implemented"); - } - - private void negotiate(String offer, NegotiationCallback callback) { - if (mNegotiationCallback != null) { - callback.onFailure("Negotiation already in progress"); - return; - } - - mNegotiationCallback = callback; - // If success will call onRemoteDescriptionSet. - connection().setRemoteDescription( - AbstractPeerConnection.SessionDescriptionType.OFFER, offer); - } - - protected void onRemoteDescriptionSet() { - // If success will call onLocalDescriptionCreatedAndSet. - connection().createAndSetLocalDescription( - AbstractPeerConnection.SessionDescriptionType.ANSWER); - } - - @Override - protected void onLocalDescriptionCreatedAndSet( - AbstractPeerConnection.SessionDescriptionType type, String description) { - assert type == AbstractPeerConnection.SessionDescriptionType.ANSWER; - - mNegotiationCallback.onSuccess(description); - mNegotiationCallback = null; - onSessionNegotiated(); - } - - protected void onSessionNegotiated() { - if (!isControlChannelOpened()) - startAutoCloseTimer(); - } - - @Override - public void iceExchange(List clientCandidates, - IceExchangeCallback callback) { - checkCalledOnSessionThread(); - if (!isStarted()) { - callback.onFailure("Session disposed"); - return; - } - - if (mNegotiationCallback != null || mIceExchangeCallback != null) { - callback.onFailure("Concurrent requests detected"); - return; - } - - mIceExchangeCallback = callback; - addIceCandidates(clientCandidates); - - // Give libjingle some time for gathering ice candidates. - postOnSessionThread(mGatheringDelayMs, new Runnable() { - @Override - public void run() { - if (isStarted()) - sendIceCandidatesBack(); - } - }); - } - - private void sendIceCandidatesBack() { - mIceExchangeCallback.onSuccess(takeIceCandidates()); - mIceExchangeCallback = null; - mIceEchangeRequested = false; - } - - @Override - protected void onControlChannelOpened() { - stopAutoCloseTimer(); - } - - @Override - protected void onFailure(String message) { - if (mNegotiationCallback != null) { - mNegotiationCallback.onFailure(message); - mNegotiationCallback = null; - } - super.onFailure(message); - } - - @Override - protected void onIceCandidate(String candidate) { - super.onIceCandidate(candidate); - if (isControlChannelOpened() && !mIceEchangeRequested) { - // New ICE candidate may improve connection even if control channel operable. - // If control channel closed client will exchange candidates anyway. - sendControlMessage(new SessionControlMessages.IceExchangeMessage()); - mIceEchangeRequested = true; - } - } - - protected SocketTunnel newSocketTunnelServer(String serverSocketName) { - return mFactory.newSocketTunnelServer(serverSocketName); - } - - private final class ClientMessageHandler extends SessionControlMessages.ClientMessageHandler { - @Override - protected void onMessage(SessionControlMessages.ClientMessage message) { - switch (message.type) { - case UNKNOWN_REQUEST: - sendControlMessage(((SessionControlMessages.UnknownRequestMessage) message) - .createResponse()); - break; - } - } - } - - @Override - protected void sendControlMessage(SessionControlMessages.Message message) { - assert message instanceof SessionControlMessages.ServerMessage; - super.sendControlMessage(message); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServiceLifetimeManager.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServiceLifetimeManager.java deleted file mode 100644 index 29f0f3b..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ServiceLifetimeManager.java +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.app.IntentService; -import android.app.Service; -import android.content.Context; -import android.os.Handler; -import android.os.Looper; -import android.os.PowerManager; - -/** - * Tracks count of running tasks and stops the service when all tasks completed. Supposed to be - * a part of a service. - * - * Usage: - * class MyService extends Service { - * public int onStartCommand(Intent intent, int flags, int startId) { - * Runnable intentHandlingTask = mLifetimeManager.startTask(startId); - * ... - * intentHandlingTask.run(); // Stops self if no other task started. - * return START_NOT_STICKY; - * } - * } - */ -class ServiceLifetimeManager { - private final Service mService; - private final String mWakeLockKey; - private int mLastStartId = -1; - private int mActiveTasks = 0; - private PowerManager.WakeLock mWakeLock; - - public ServiceLifetimeManager(Service service, String wakeLockKey) { - // IntentService is incompatible with this class because it manages lifetime on its own. - assert !(service instanceof IntentService); - - mService = service; - mWakeLockKey = wakeLockKey; - } - - public Runnable startTask(int startId) { - mLastStartId = startId; - return startTask(); - } - - public Runnable startTask() { - assert isCalledOnServiceLooper(); - if (mActiveTasks == 0) { - if (mWakeLock == null) { - PowerManager pm = (PowerManager) mService.getSystemService(Context.POWER_SERVICE); - mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mWakeLockKey); - } - mWakeLock.acquire(); - } - mActiveTasks++; - return new TaskCompletionHandler(); - } - - private boolean isCalledOnServiceLooper() { - return mService.getMainLooper() == Looper.myLooper(); - } - - private class TaskCompletionHandler implements Runnable { - private boolean mCompleted = false; - - @Override - public void run() { - if (!isCalledOnServiceLooper()) { - new Handler(mService.getMainLooper()).post(this); - return; - } - if (mCompleted) return; - - if (--mActiveTasks == 0) { - mWakeLock.release(); - mService.stopSelf(mLastStartId); - } - mCompleted = true; - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionBase.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionBase.java deleted file mode 100644 index 11fd9b6..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionBase.java +++ /dev/null @@ -1,435 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -/** - * Base class for ServerSession and ClientSession. Both opens a control channel and a default - * tunnel. Control channel designated to exchange messages defined in SessionControlMessages. - * - * Signaling communication between client and server works in request/response manner. It's more - * restrictive than traditional bidirectional signaling channel but give more freedom in - * implementing signaling. Main motivation is that GCD provides API what works in that way. - * - * Session is initiated by a client. It creates an offer and sends it along with RTC configuration. - * Server sends an answer in response. Once session negotiated client starts ICE candidates - * exchange. It periodically sends own candidates and peeks server's ones. Periodic ICE exchange - * stops when control channel opens. It resumes if connections state turns to DISCONNECTED (because - * server may generate ICE candidates to recover connectivity but may not notify through - * control channel). ICE exchange in CONNECTED state designated to let improve connection - * when network configuration changed. - * - * If session is not started (or resumed) after mAutoCloseTimeoutMs it closes itself. - * - * Only default tunnel is supported at the moment. It designated for DevTools UNIX socket. - * Additional tunnels may be useful for: 1) reverse port forwarding and 2) tunneling - * WebView DevTools sockets of other applications. Additional tunnels negotiation should - * be implemented by adding new types of control messages. Dynamic tunnel configuration - * will need support for session renegotiation. - * - * Session is a single threaded object. Until started owner is responsible to synchronizing access - * to it. When started it must be called on the thread of SessionBase.Executor. - * All WebRTC callbacks are forwarded on this thread. - */ -public abstract class SessionBase { - private static final int CONTROL_CHANNEL_ID = 0; - private static final int DEFAULT_TUNNEL_CHANNEL_ID = 1; - - private final Executor mExecutor; - protected final SessionDependencyFactory mFactory; - private AbstractPeerConnection mConnection; - private AbstractDataChannel mControlChannel; - private List mCandidates = new ArrayList(); - private boolean mControlChannelOpened = false; - private boolean mConnected = false; - private Cancellable mAutoCloseTask; - private SessionControlMessages.MessageHandler mControlMessageHandler; - private final Map mTunnels = - new HashMap(); - private EventListener mEventListener; - - protected int mAutoCloseTimeoutMs = 30000; - - /** - * Allows to post tasks on the thread where the sessions lives. - */ - public interface Executor { - Cancellable postOnSessionThread(int delayMs, Runnable runnable); - boolean isCalledOnSessionThread(); - } - - /** - * Interface for cancelling scheduled tasks. - */ - public interface Cancellable { - void cancel(); - } - - /** - * Representation of server session. All methods are delivered through - * signaling channel (except test configurations). Server session is accessible - * in request/response manner. - */ - public interface ServerSessionInterface { - /** - * Starts session with specified RTC configuration and offer. - */ - void startSession(RTCConfiguration config, - String offer, - NegotiationCallback callback); - - /** - * Renegoteates session. Needed when tunnels added/removed on the fly. - */ - void renegotiate(String offer, NegotiationCallback callback); - - /** - * Sends client's ICE candidates to the server and peeks server's ICE candidates. - */ - void iceExchange(List clientCandidates, IceExchangeCallback callback); - } - - /** - * Base interface for server callbacks. - */ - public interface ServerCallback { - void onFailure(String errorMessage); - } - - /** - * Server's response to startSession and renegotiate methods. - */ - public interface NegotiationCallback extends ServerCallback { - void onSuccess(String answer); - } - - /** - * Server's response on iceExchange method. - */ - public interface IceExchangeCallback extends ServerCallback { - void onSuccess(List serverCandidates); - } - - /** - * Listener of session's events. - */ - public interface EventListener { - void onCloseSelf(); - } - - protected SessionBase(SessionDependencyFactory factory, - Executor executor, - SocketTunnel defaultTunnel) { - mExecutor = executor; - mFactory = factory; - addTunnel(DEFAULT_TUNNEL_CHANNEL_ID, defaultTunnel); - } - - public final void dispose() { - checkCalledOnSessionThread(); - - if (isStarted()) stop(); - - for (SocketTunnel tunnel : mTunnels.values()) { - tunnel.dispose(); - } - } - - public void setEventListener(EventListener listener) { - checkCalledOnSessionThread(); - - mEventListener = listener; - } - - protected AbstractPeerConnection connection() { - return mConnection; - } - - protected boolean doesTunnelExist(int channelId) { - return mTunnels.containsKey(channelId); - } - - private final void addTunnel(int channelId, SocketTunnel tunnel) { - assert !mTunnels.containsKey(channelId); - assert !tunnel.isBound(); - // Tunnel renegotiation not implemented. - assert channelId == DEFAULT_TUNNEL_CHANNEL_ID && !isStarted(); - - mTunnels.put(channelId, tunnel); - } - - protected void removeTunnel(int channelId) { - assert mTunnels.containsKey(channelId); - mTunnels.get(channelId).unbind().dispose(); - mTunnels.remove(channelId); - } - - protected final boolean isControlChannelOpened() { - return mControlChannelOpened; - } - - protected final boolean isConnected() { - return mConnected; - } - - protected final void postOnSessionThread(Runnable runnable) { - postOnSessionThread(0, runnable); - } - - protected final Cancellable postOnSessionThread(int delayMs, Runnable runnable) { - return mExecutor.postOnSessionThread(delayMs, runnable); - } - - protected final void checkCalledOnSessionThread() { - assert mExecutor.isCalledOnSessionThread(); - } - - public final boolean isStarted() { - return mConnection != null; - } - - /** - * Creates and configures peer connection and sets a control message handler. - */ - protected void start(RTCConfiguration config, - SessionControlMessages.MessageHandler handler) { - assert !isStarted(); - - mConnection = mFactory.createPeerConnection(config, new ConnectionObserver()); - mControlChannel = mConnection.createDataChannel(CONTROL_CHANNEL_ID); - mControlMessageHandler = handler; - mControlChannel.registerObserver(new ControlChannelObserver()); - - for (Map.Entry entry : mTunnels.entrySet()) { - int channelId = entry.getKey(); - SocketTunnel tunnel = entry.getValue(); - tunnel.bind(connection().createDataChannel(channelId)); - } - } - - /** - * Disposed objects created in |start|. - */ - public void stop() { - checkCalledOnSessionThread(); - - assert isStarted(); - - stopAutoCloseTimer(); - - for (SocketTunnel tunnel : mTunnels.values()) { - tunnel.unbind().dispose(); - } - - AbstractPeerConnection connection = mConnection; - mConnection = null; - assert !isStarted(); - - mControlChannel.unregisterObserver(); - mControlMessageHandler = null; - mControlChannel.dispose(); - mControlChannel = null; - - // Dispose connection after data channels. - connection.dispose(); - } - - protected abstract void onRemoteDescriptionSet(); - protected abstract void onLocalDescriptionCreatedAndSet( - AbstractPeerConnection.SessionDescriptionType type, String description); - protected abstract void onControlChannelOpened(); - - protected void onControlChannelClosed() { - closeSelf(); - } - - protected void onIceConnectionChange() {} - - private void handleFailureOnSignalingThread(final String message) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (isStarted()) - onFailure(message); - } - }); - } - - protected final void startAutoCloseTimer() { - assert mAutoCloseTask == null; - assert isStarted(); - mAutoCloseTask = postOnSessionThread(mAutoCloseTimeoutMs, new Runnable() { - @Override - public void run() { - assert isStarted(); - - mAutoCloseTask = null; - closeSelf(); - } - }); - } - - protected final void stopAutoCloseTimer() { - if (mAutoCloseTask != null) { - mAutoCloseTask.cancel(); - mAutoCloseTask = null; - } - } - - protected void closeSelf() { - stop(); - if (mEventListener != null) { - mEventListener.onCloseSelf(); - } - } - - // Returns collected candidates (for sending to the remote session) and removes them. - protected List takeIceCandidates() { - List result = new ArrayList(); - result.addAll(mCandidates); - mCandidates.clear(); - return result; - } - - protected void addIceCandidates(List candidates) { - for (String candidate : candidates) { - mConnection.addIceCandidate(candidate); - } - } - - protected void onFailure(String message) { - closeSelf(); - } - - protected void onIceCandidate(String candidate) { - mCandidates.add(candidate); - } - - /** - * Receives callbacks from the peer connection on the signaling thread. Forwards them - * on the session thread. All session event handling methods assume session started (prevents - * disposed objects). It drops callbacks it closed. - */ - private final class ConnectionObserver implements AbstractPeerConnection.Observer { - @Override - public void onFailure(final String description) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - SessionBase.this.onFailure(description); - } - }); - } - - @Override - public void onLocalDescriptionCreatedAndSet( - final AbstractPeerConnection.SessionDescriptionType type, - final String description) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - SessionBase.this.onLocalDescriptionCreatedAndSet(type, description); - } - }); - } - - @Override - public void onRemoteDescriptionSet() { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - SessionBase.this.onRemoteDescriptionSet(); - } - }); - } - - @Override - public void onIceCandidate(final String candidate) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - SessionBase.this.onIceCandidate(candidate); - } - }); - } - - @Override - public void onIceConnectionChange(final boolean connected) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - mConnected = connected; - SessionBase.this.onIceConnectionChange(); - } - }); - } - } - - /** - * Receives callbacks from the control channel. Forwards them on the session thread. - */ - private final class ControlChannelObserver implements AbstractDataChannel.Observer { - @Override - public void onStateChange(final AbstractDataChannel.State state) { - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted()) return; - mControlChannelOpened = state == AbstractDataChannel.State.OPEN; - - if (mControlChannelOpened) { - onControlChannelOpened(); - } else { - onControlChannelClosed(); - } - } - }); - } - - @Override - public void onMessage(ByteBuffer message) { - final byte[] bytes = new byte[message.remaining()]; - message.get(bytes); - postOnSessionThread(new Runnable() { - @Override - public void run() { - if (!isStarted() || mControlMessageHandler == null) return; - - try { - mControlMessageHandler.readMessage(bytes); - } catch (SessionControlMessages.InvalidFormatException e) { - // TODO(serya): handle - } - } - }); - } - } - - protected void sendControlMessage(SessionControlMessages.Message message) { - assert mControlChannelOpened; - - byte[] bytes = SessionControlMessages.toByteArray(message); - ByteBuffer rawMessage = ByteBuffer.allocateDirect(bytes.length); - rawMessage.put(bytes); - - sendControlMessage(rawMessage); - } - - private void sendControlMessage(ByteBuffer rawMessage) { - rawMessage.limit(rawMessage.position()); - rawMessage.position(0); - mControlChannel.send(rawMessage, AbstractDataChannel.MessageType.TEXT); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionControlMessages.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionControlMessages.java deleted file mode 100644 index 4c16520..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionControlMessages.java +++ /dev/null @@ -1,251 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.util.JsonReader; -import android.util.JsonWriter; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStreamWriter; - -/** - * Defines protocol of control channel of SessionBase. Messages are JSON serializable - * and transferred through AbstractDataChannel. - */ -public final class SessionControlMessages { - private SessionControlMessages() { - throw new RuntimeException("Class not intended to instantiate"); - } - - /** - * Types of messages that client sends to server. - */ - enum ClientMessageType { - UNKNOWN_REQUEST - } - - /** - * Types of messages that servers sends to client. - */ - enum ServerMessageType { - ICE_EXCHANGE, - UNKNOWN_RESPONSE - } - - /** - * Base class for all messages. - */ - public abstract static class Message { - public final T type; - - protected Message(T type) { - this.type = type; - } - - public void write(JsonWriter writer) throws IOException { - writer.name("type"); - writer.value(type.toString()); - } - } - - /** - * Base calss for messages that client sends to server. - */ - public abstract static class ClientMessage extends Message { - protected ClientMessage(ClientMessageType type) { - super(type); - } - } - - /** - * Base class for messages that server sends to client. - */ - public abstract static class ServerMessage extends Message { - protected ServerMessage(ServerMessageType type) { - super(type); - } - } - - /** - * Server sends this message when it has ICE candidates to exchange. Client initiates - * ICE exchange over signaling channel. - */ - public static final class IceExchangeMessage extends ServerMessage { - public IceExchangeMessage() { - super(ServerMessageType.ICE_EXCHANGE); - } - } - - /** - * Server response on unrecognized client message. - */ - public static final class UnknownResponseMessage extends ServerMessage { - public final String rawRequestType; - - public UnknownResponseMessage(String rawRequestType) { - super(ServerMessageType.UNKNOWN_RESPONSE); - this.rawRequestType = rawRequestType; - } - - @Override - public void write(JsonWriter writer) throws IOException { - super.write(writer); - writer.name("rawRequestType"); - writer.value(rawRequestType.toString()); - } - } - - /** - * Helper class to represent message of unknown type. Should not be sent. - */ - public static final class UnknownRequestMessage extends ClientMessage { - public final String rawType; - - public UnknownRequestMessage(String rawType) { - super(ClientMessageType.UNKNOWN_REQUEST); - this.rawType = rawType; - } - - @Override - public void write(JsonWriter writer) throws IOException { - throw new RuntimeException("Should not be serialized"); - } - - public UnknownResponseMessage createResponse() { - return new UnknownResponseMessage(rawType); - } - } - - private static > T getMessageType( - Class enumType, String rawType, T defaultType) throws IOException { - try { - return Enum.valueOf(enumType, rawType); - } catch (IllegalArgumentException e) { - if (defaultType != null) - return defaultType; - throw new IOException("Invalid message type " + rawType); - } - } - - public static void write(JsonWriter writer, Message message) throws IOException { - writer.beginObject(); - message.write(writer); - writer.endObject(); - } - - public static ClientMessage readClientMessage(JsonReader reader) throws IOException { - String rawType = ""; - boolean success = false; - - reader.beginObject(); - while (reader.hasNext()) { - String name = reader.nextName(); - if ("type".equals(name)) { - rawType = reader.nextString(); - } - } - reader.endObject(); - - switch (getMessageType(ClientMessageType.class, - rawType, - ClientMessageType.UNKNOWN_REQUEST)) { - case UNKNOWN_REQUEST: - return new UnknownRequestMessage(rawType); - } - throw new IOException("Invalid message"); - } - - public static ServerMessage readServerMessage(JsonReader reader) throws IOException { - String rawType = ""; - String rawRequestType = null; - - reader.beginObject(); - while (reader.hasNext()) { - String name = reader.nextName(); - if ("type".equals(name)) { - rawType = reader.nextString(); - } else if ("rawRequestType".equals(name)) { - rawRequestType = reader.nextString(); - } - } - reader.endObject(); - - switch (getMessageType(ServerMessageType.class, rawType, null)) { - case ICE_EXCHANGE: - return new IceExchangeMessage(); - case UNKNOWN_RESPONSE: - return new UnknownResponseMessage(rawRequestType); - } - throw new IOException("Invalid message"); - } - - /** - * Base class for client and server message handlers. - */ - public abstract static class MessageHandler { - protected abstract void readMessage(JsonReader reader) throws IOException; - - public boolean readMessage(byte[] bytes) throws InvalidFormatException { - try { - readMessage(new JsonReader(new InputStreamReader(new ByteArrayInputStream(bytes)))); - return true; - } catch (IOException e) { - throw new InvalidFormatException(e); - } - } - } - - /** - * Exception when parsing or handling message. - */ - public static class InvalidFormatException extends IOException { - public InvalidFormatException(IOException e) { - super(e); - } - - public InvalidFormatException(String message) { - super(message); - } - } - - /** - * Base class for handler of server messages (to be created on client). - */ - public abstract static class ServerMessageHandler extends MessageHandler { - @Override - protected void readMessage(JsonReader reader) throws IOException { - onMessage(readServerMessage(reader)); - } - - protected abstract void onMessage(ServerMessage message); - } - - /** - * Base class for handler of client messages (to be created on server). - */ - public abstract static class ClientMessageHandler extends MessageHandler { - @Override - public void readMessage(JsonReader reader) throws IOException { - onMessage(readClientMessage(reader)); - } - - protected abstract void onMessage(ClientMessage message); - } - - public static byte[] toByteArray(Message message) { - ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); - JsonWriter writer = new JsonWriter(new OutputStreamWriter(byteStream)); - try { - write(writer, message); - writer.close(); - return byteStream.toByteArray(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java deleted file mode 100644 index e90e8ce..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactory.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -/** - * Implements AbstractDataChannel and AbstractPeerConnection on top of org.webrtc.* API. - * Isolation is needed because some configuration of DevTools bridge may not be based on - * Java API. - * In addition abstraction layer isolates SessionBase from complexity of underlying API - * beside used features. - */ -public abstract class SessionDependencyFactory { - private interface Constructor { - SessionDependencyFactory newInstance(); - } - - private static Constructor sConstructor; - - public static SessionDependencyFactory newInstance() { - return sConstructor.newInstance(); - } - - public static void init(final Class c) { - sConstructor = new Constructor() { - @Override - public SessionDependencyFactory newInstance() { - try { - return c.newInstance(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - }; - } - - public abstract AbstractPeerConnection createPeerConnection( - RTCConfiguration config, AbstractPeerConnection.Observer observer); - - public abstract SocketTunnel newSocketTunnelServer(String socketName); - - public abstract void dispose(); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryNative.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryNative.java deleted file mode 100644 index cac78a5..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryNative.java +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import org.chromium.base.CalledByNative; -import org.chromium.base.JNINamespace; - -import java.nio.ByteBuffer; - -/** - * Native implementation of session dependency factory on top of C++ - * libjingle API. - */ -@JNINamespace("devtools_bridge::android") -public class SessionDependencyFactoryNative extends SessionDependencyFactory { - private final long mFactoryPtr; - - public SessionDependencyFactoryNative() { - mFactoryPtr = nativeCreateFactory(); - assert mFactoryPtr != 0; - } - - @Override - public AbstractPeerConnection createPeerConnection( - RTCConfiguration config, AbstractPeerConnection.Observer observer) { - assert config != null; - assert observer != null; - - long configPtr = nativeCreateConfig(); - for (RTCConfiguration.IceServer server : config.iceServers) { - nativeAddIceServer(configPtr, server.uri, server.username, server.credential); - } - - return new PeerConnectionImpl(mFactoryPtr, configPtr, observer); - } - - @Override - public SocketTunnel newSocketTunnelServer(String socketBase) { - return new SocketTunnelServerImpl(mFactoryPtr, socketBase); - } - - @Override - public void dispose() { - nativeDestroyFactory(mFactoryPtr); - } - - private static final class PeerConnectionImpl extends AbstractPeerConnection { - private final long mConnectionPtr; - - // Takes ownership on |configPtr|. - public PeerConnectionImpl( - long factoryPtr, long configPtr, - AbstractPeerConnection.Observer observer) { - mConnectionPtr = nativeCreatePeerConnection(factoryPtr, configPtr, observer); - assert mConnectionPtr != 0; - } - - @Override - public void createAndSetLocalDescription(SessionDescriptionType type) { - switch (type) { - case OFFER: - nativeCreateAndSetLocalOffer(mConnectionPtr); - break; - - case ANSWER: - nativeCreateAndSetLocalAnswer(mConnectionPtr); - break; - } - } - - @Override - public void setRemoteDescription(SessionDescriptionType type, String description) { - switch (type) { - case OFFER: - nativeSetRemoteOffer(mConnectionPtr, description); - break; - - case ANSWER: - nativeSetRemoteAnswer(mConnectionPtr, description); - break; - } - } - - @Override - public void addIceCandidate(String candidate) { - // TODO(serya): Handle IllegalArgumentException exception. - IceCandidate parsed = IceCandidate.fromString(candidate); - nativeAddIceCandidate(mConnectionPtr, parsed.sdpMid, parsed.sdpMLineIndex, parsed.sdp); - } - - @Override - public void dispose() { - nativeDestroyPeerConnection(mConnectionPtr); - } - - @Override - public AbstractDataChannel createDataChannel(int channelId) { - return new DataChannelImpl(nativeCreateDataChannel(mConnectionPtr, channelId)); - } - } - - private static final class DataChannelImpl extends AbstractDataChannel { - private final long mChannelPtr; - - public DataChannelImpl(long ptr) { - assert ptr != 0; - mChannelPtr = ptr; - } - - long nativePtr() { - return mChannelPtr; - } - - @Override - public void registerObserver(Observer observer) { - nativeRegisterDataChannelObserver(mChannelPtr, observer); - } - - @Override - public void unregisterObserver() { - nativeUnregisterDataChannelObserver(mChannelPtr); - } - - @Override - public void send(ByteBuffer message, MessageType type) { - assert message.position() == 0; - int length = message.limit(); - assert length > 0; - - switch (type) { - case BINARY: - nativeSendBinaryMessage(mChannelPtr, message, length); - break; - - case TEXT: - nativeSendTextMessage(mChannelPtr, message, length); - break; - } - } - - @Override - public void close() { - nativeCloseDataChannel(mChannelPtr); - } - - @Override - public void dispose() { - nativeDestroyDataChannel(mChannelPtr); - } - } - - private static class SocketTunnelServerImpl implements SocketTunnel { - private final String mSocketName; - private final long mFactoryPtr; - private DataChannelImpl mDataChannel; - private long mTunnelPtr; - - public SocketTunnelServerImpl(long factoryPtr, String socketName) { - mFactoryPtr = factoryPtr; - mSocketName = socketName; - } - - @Override - public void bind(AbstractDataChannel dataChannel) { - mDataChannel = (DataChannelImpl) dataChannel; - mTunnelPtr = nativeCreateSocketTunnelServer( - mFactoryPtr, mDataChannel.nativePtr(), mSocketName); - } - - @Override - public AbstractDataChannel unbind() { - AbstractDataChannel result = mDataChannel; - nativeDestroySocketTunnelServer(mTunnelPtr); - mTunnelPtr = 0; - mDataChannel = null; - return result; - } - - @Override - public boolean isBound() { - return mDataChannel != null; - } - - @Override - public void dispose() { - assert !isBound(); - } - } - - // Peer connection callbacks. - - @CalledByNative - private static void notifyLocalOfferCreatedAndSetSet(Object observer, String description) { - ((AbstractPeerConnection.Observer) observer).onLocalDescriptionCreatedAndSet( - AbstractPeerConnection.SessionDescriptionType.OFFER, description); - } - - @CalledByNative - private static void notifyLocalAnswerCreatedAndSetSet(Object observer, String description) { - ((AbstractPeerConnection.Observer) observer).onLocalDescriptionCreatedAndSet( - AbstractPeerConnection.SessionDescriptionType.ANSWER, description); - } - - @CalledByNative - private static void notifyRemoteDescriptionSet(Object observer) { - ((AbstractPeerConnection.Observer) observer).onRemoteDescriptionSet(); - } - - @CalledByNative - private static void notifyConnectionFailure(Object observer, String description) { - ((AbstractPeerConnection.Observer) observer).onFailure(description); - } - - @CalledByNative - private static void notifyIceCandidate( - Object observer, String sdpMid, int sdpMLineIndex, String sdp) { - ((AbstractPeerConnection.Observer) observer) - .onIceCandidate(new AbstractPeerConnection.IceCandidate( - sdpMid, sdpMLineIndex, sdp).toString()); - } - - @CalledByNative - private static void notifyIceConnectionChange(Object observer, boolean connected) { - ((AbstractPeerConnection.Observer) observer) - .onIceConnectionChange(connected); - } - - // Data channel callbacks. - - @CalledByNative - private static void notifyChannelOpen(Object observer) { - ((AbstractDataChannel.Observer) observer) - .onStateChange(AbstractDataChannel.State.OPEN); - } - - @CalledByNative - private static void notifyChannelClose(Object observer) { - ((AbstractDataChannel.Observer) observer) - .onStateChange(AbstractDataChannel.State.CLOSED); - } - - @CalledByNative - private static void notifyMessage(Object observer, ByteBuffer message) { - ((AbstractDataChannel.Observer) observer) - .onMessage(message); - } - - private static native long nativeCreateFactory(); - private static native void nativeDestroyFactory(long factoryPtr); - - private static native long nativeCreateConfig(); - private static native void nativeAddIceServer( - long configPtr, String uri, String username, String credential); - - // Takes ownership on |configPtr|. - private static native long nativeCreatePeerConnection( - long factoryPtr, long configPtr, Object observer); - private static native void nativeDestroyPeerConnection(long connectionPtr); - - private static native void nativeCreateAndSetLocalOffer(long connectionPtr); - private static native void nativeCreateAndSetLocalAnswer(long connectionPtr); - private static native void nativeSetRemoteOffer(long connectionPtr, String description); - private static native void nativeSetRemoteAnswer(long connectionPtr, String description); - private static native void nativeAddIceCandidate( - long peerConnectionPtr, String sdpMid, int sdpMLineIndex, String sdp); - - private static native long nativeCreateDataChannel(long connectionPtr, int channelId); - private static native void nativeDestroyDataChannel(long channelPtr); - - private static native void nativeRegisterDataChannelObserver( - long channelPtr, Object observer); - private static native void nativeUnregisterDataChannelObserver(long channelPtr); - private static native void nativeSendBinaryMessage( - long channelPtr, ByteBuffer message, int size); - private static native void nativeSendTextMessage(long channelPtr, ByteBuffer message, int size); - private static native void nativeCloseDataChannel(long channelPtr); - - private static native long nativeCreateSocketTunnelServer( - long factoryPtr, long channelPtr, String socketName); - private static native void nativeDestroySocketTunnelServer(long tunnelPtr); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SignalingReceiver.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SignalingReceiver.java deleted file mode 100644 index fb914d8..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SignalingReceiver.java +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import java.util.List; - -/** - * Signaling channel interface. Methods are marshalled through GCM. - * Direct calling supported for tests. - * - * Primary reason of the signaling channel is supporting debugging sessions (so why - * it looks like SessionBase.ServerSessionInterface with session ids). It also - * may be used for retrieving information when establishing session is not appropriate. - */ -public interface SignalingReceiver { - /** - * Starts new session and assigns sessionId to it. Passes all arguments to - * the ServerSession object. Session ID must be globay unique (like long random) to - * avoid conflicts among clients. - */ - void startSession( - String sessionId, - RTCConfiguration config, - String offer, - SessionBase.NegotiationCallback callback); - - /** - * Passes call to the appropriate ServerSession object (if it still exists). - */ - void renegotiate( - String sessionId, - String offer, - SessionBase.NegotiationCallback callback); - - /** - * Passes call to the appropriate ServerSession object (if it still exists). - */ - void iceExchange( - String sessionId, - List clientCandidates, - SessionBase.IceExchangeCallback callback); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SocketTunnel.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SocketTunnel.java deleted file mode 100644 index f7670e8..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/SocketTunnel.java +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -/** - * Interface for client or server socket tunnel. Tunnels a socket over a data channel. - * Client tunnel should be bound to one side and server tunnel to another. - * - * Data flow schema looks like this: - * - * DevToolsServer - * <-unix socket-> - * SocketTunnelServer - * <-data channel-> - * SocketTunnelClient - * <- unix socket -> - * Client (DevTools frontend) - */ -interface SocketTunnel { - void bind(AbstractDataChannel dataChannel); - AbstractDataChannel unbind(); - boolean isBound(); - - void dispose(); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/ApiaryClientFactory.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/ApiaryClientFactory.java deleted file mode 100644 index 92df28a..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/ApiaryClientFactory.java +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.net.http.AndroidHttpClient; - -import org.chromium.base.JNINamespace; - -/** - * Factory for creating clients for external APIs. - */ -@JNINamespace("devtools_bridge::android") -public class ApiaryClientFactory { - private static final String USER_AGENT = "DevTools bridge"; - - public static final String OAUTH_SCOPE = "https://www.googleapis.com/auth/clouddevices"; - - protected final AndroidHttpClient mHttpClient = AndroidHttpClient.newInstance(USER_AGENT); - - /** - * Creates a new GCD client with auth token. - */ - public GCDClient newGCDClient(String oAuthToken) { - return new GCDClient(mHttpClient, getAPIKey(), oAuthToken); - } - - /** - * Creates a new anonymous client. GCD requires client been not authenticated by user or - * device credentials for finalizing registration. - */ - public GCDClient newAnonymousGCDClient() { - return new GCDClient(mHttpClient, nativeGetAPIKey()); - } - - public OAuthClient newOAuthClient() { - return new OAuthClient( - mHttpClient, OAUTH_SCOPE, getOAuthClientId(), nativeGetOAuthClientSecret()); - } - - public BlockingGCMRegistrar newGCMRegistrar() { - return new BlockingGCMRegistrar(); - } - - public void close() { - mHttpClient.close(); - } - - public String getOAuthClientId() { - return nativeGetOAuthClientId(); - } - - protected String getAPIKey() { - return nativeGetAPIKey(); - } - - private native String nativeGetAPIKey(); - private native String nativeGetOAuthClientId(); - private native String nativeGetOAuthClientSecret(); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/BlockingGCMRegistrar.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/BlockingGCMRegistrar.java deleted file mode 100644 index 3cf5eaf..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/BlockingGCMRegistrar.java +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Looper; - -import com.google.ipc.invalidation.external.client.contrib.MultiplexingGcmListener; - -import java.io.IOException; -import java.util.concurrent.CountDownLatch; - -/** - * Helps using MultiplexingGcmListene in blocking manner. If the app has not registered in GCM - * it sends registration request and waits for an intent with registration ID. - * Waiting may be interrupted. Must not be used on UI (or Context's main) looper. - */ -public final class BlockingGCMRegistrar { - public String blockingGetRegistrationId(Context context) - throws InterruptedException, IOException { - assert context != null; - assert context.getMainLooper() != Looper.myLooper(); - - Receiver receiver = new Receiver(); - receiver.register(context); - try { - // MultiplexingGcmListener starts registration if the app has not registered yet. - String result = MultiplexingGcmListener.initializeGcm(context); - if (result != null && !result.isEmpty()) return result; - return receiver.awaitRegistrationId(); - } finally { - receiver.unregister(context); - } - } - - private static class Receiver extends BroadcastReceiver { - private final CountDownLatch mDone = new CountDownLatch(1); - - private String mRegistrationId; - - public void register(Context context) { - IntentFilter filter = new IntentFilter(); - filter.addCategory(context.getPackageName()); - filter.addAction(MultiplexingGcmListener.Intents.ACTION); - context.registerReceiver(this, filter); - } - - public void unregister(Context context) { - context.unregisterReceiver(this); - } - - public String awaitRegistrationId() throws InterruptedException, IOException { - mDone.await(); - if (mRegistrationId != null) { - return mRegistrationId; - } - throw new IOException(); - } - - @Override - public void onReceive(Context context, Intent intent) { - assert intent.getAction().equals(MultiplexingGcmListener.Intents.ACTION); - - if (!intent.getBooleanExtra( - MultiplexingGcmListener.Intents.EXTRA_OP_REGISTERED, false)) { - return; - } - - mRegistrationId = intent.getStringExtra( - MultiplexingGcmListener.Intents.EXTRA_DATA_REG_ID); - - if (mRegistrationId != null) { - mDone.countDown(); - } - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/GCDClient.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/GCDClient.java deleted file mode 100644 index 7a3f52d..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/GCDClient.java +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.util.JsonReader; - -import org.apache.http.HttpResponse; -import org.apache.http.client.HttpClient; -import org.apache.http.client.HttpResponseException; -import org.apache.http.client.ResponseHandler; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.entity.StringEntity; - -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.gcd.InstanceCredential; -import org.chromium.components.devtools_bridge.gcd.InstanceDescription; -import org.chromium.components.devtools_bridge.gcd.MessageReader; -import org.chromium.components.devtools_bridge.gcd.MessageWriter; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URI; - -/** - * Client for accessing GCD API. - */ -public class GCDClient { - private static final String API_BASE = "https://www.googleapis.com/clouddevices/v1"; - public static final String ENCODING = "UTF-8"; - protected static final String CONTENT_TYPE = "application/json; charset=" + ENCODING; - - protected final HttpClient mHttpClient; - private final String mAPIKey; - private final String mOAuthToken; - - GCDClient(HttpClient httpClient, String apiKey, String oAuthToken) { - mHttpClient = httpClient; - mAPIKey = apiKey; - mOAuthToken = oAuthToken; - } - - GCDClient(HttpClient httpClient, String apiKey) { - this(httpClient, apiKey, null); - } - - /** - * Creation of a registration ticket is the first step in instance registration. Client must - * have user credentials. If the ticket has been registered it will be associated with the - * user. Next step is registration ticket patching. - */ - public final String createRegistrationTicket() throws IOException { - assert mOAuthToken != null; - - return mHttpClient.execute( - newHttpPost("/registrationTickets", "{\"userEmail\":\"me\"}"), - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - return new MessageReader(reader).readTicketId(); - } - }); - } - - /** - * Patching registration ticket. GCD gets device definition including commands metadata, - * GCM channel description and user-visible instance name. - */ - public final void patchRegistrationTicket(String ticketId, InstanceDescription description) - throws IOException { - String content = new MessageWriter().writeTicketPatch(description).close().toString(); - - mHttpClient.execute( - newHttpPatch("/registrationTickets/" + ticketId, content), - new EmptyResponseHandler()); - } - - /** - * Finalizing registration. Client must be anonymous (GCD requirement). GCD provides - * instance credentials needed for handling commands. - */ - public final InstanceCredential finalizeRegistration(String ticketId) throws IOException { - return mHttpClient.execute( - newHttpPost("/registrationTickets/" + ticketId + "/finalize", ""), - new JsonResponseHandler() { - @Override - public InstanceCredential readResponse(JsonReader reader) throws IOException { - return new MessageReader(reader).readInstanceCredential(); - } - }); - } - - public final void patchInstanceGCMChannel(String instanceId, String gcmChannelId) - throws IOException { - String content = new MessageWriter() - .writeDeviceGCMChannelPatch(gcmChannelId).close().toString(); - - mHttpClient.execute( - newHttpPatch("/devices/" + instanceId, content), - new EmptyResponseHandler()); - } - - /** - * Deletes registered instance (unregisters). If client has instance credentials then - * instanceId must be it's own ID. If client has user credentials then instance must belong - * to the user. - */ - public void deleteInstance(String instanceId) throws IOException { - mHttpClient.execute( - newHttpDelete("/devices/" + instanceId), - new EmptyResponseHandler()); - } - - /** - * Patches the command (previously received with Notification) with out-parameters or - * an error message. - */ - public final void patchCommand(Command command) throws IOException { - String content = new MessageWriter().writeCommandPatch(command).close().toString(); - - mHttpClient.execute( - newHttpPatch("/commands/" + command.id, content), - new EmptyResponseHandler()); - } - - protected final HttpGet newHttpGet(String path) { - return prepare(new HttpGet(buildUrl(path))); - } - - protected final HttpPost newHttpPost(String path, String content) - throws UnsupportedEncodingException { - return prepare(new HttpPost(buildUrl(path)), content); - } - - protected final HttpPost newHttpPost(String path, String query, String content) - throws UnsupportedEncodingException { - return prepare(new HttpPost(buildUrl(path, query)), content); - } - - protected final HttpPatch newHttpPatch(String path, String content) - throws UnsupportedEncodingException { - return prepare(new HttpPatch(buildUrl(path)), content); - } - - protected final HttpDelete newHttpDelete(String path) { - return prepare(new HttpDelete(buildUrl(path))); - } - - private String buildUrl(String path) { - return API_BASE + path + "?key=" + mAPIKey; - } - - private String buildUrl(String path, String query) { - return API_BASE + path + "?" + query + "&key=" + mAPIKey; - } - - private T prepare(T request, String content) - throws UnsupportedEncodingException { - request.setEntity(new StringEntity(content, ENCODING)); - request.addHeader("Content-Type", CONTENT_TYPE); - return prepare(request); - } - - private T prepare(T request) { - if (mOAuthToken != null) { - request.addHeader("Authorization", "Bearer " + mOAuthToken); - } - return request; - } - - private static final class HttpPatch extends HttpEntityEnclosingRequestBase { - public HttpPatch(String uri) { - setURI(URI.create(uri)); - } - - public String getMethod() { - return "PATCH"; - } - } - - private static class EmptyResponseHandler implements ResponseHandler { - @Override - public Void handleResponse(HttpResponse response) throws HttpResponseException { - JsonResponseHandler.checkStatus(response); - return null; - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandler.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandler.java deleted file mode 100644 index 1700cc5..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.util.JsonReader; - -import org.apache.http.HttpEntity; -import org.apache.http.HttpResponse; -import org.apache.http.StatusLine; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpResponseException; -import org.apache.http.client.ResponseHandler; - -import java.io.IOException; -import java.io.InputStreamReader; - -/** - * Base class for a ResponseHandler that reads response with JsonReader. Like BasicResponseHandler - * throws HttpResponseException if response code >= 300. - * - * It catchs JsonReader's runtime exception (IllegalStateException and IllegalArgumentException) - * and wraps them into ResponseFormatException. - */ -abstract class JsonResponseHandler implements ResponseHandler { - public static void checkStatus(HttpResponse response) throws HttpResponseException { - StatusLine statusLine = response.getStatusLine(); - if (response.getStatusLine().getStatusCode() >= 300) { - throw new HttpResponseException( - statusLine.getStatusCode(), statusLine.getReasonPhrase()); - } - } - - @Override - public final T handleResponse(HttpResponse response) - throws IOException, ClientProtocolException { - checkStatus(response); - HttpEntity entity = response.getEntity(); - if (entity == null) { - throw new ClientProtocolException("Missing content"); - } - JsonReader reader = new JsonReader(new InputStreamReader(entity.getContent())); - try { - T result = readResponse(reader); - reader.close(); - - if (result == null) { - throw new ClientProtocolException("Missing result"); - } - - return result; - } catch (IllegalStateException e) { - throw new ResponseFormatException(e); - } catch (IllegalArgumentException e) { - throw new ResponseFormatException(e); - } - } - - public abstract T readResponse(JsonReader reader) - throws IOException, ResponseFormatException; - - public static class ResponseFormatException extends ClientProtocolException { - public ResponseFormatException(RuntimeException readerException) { - super(readerException); - } - - public ResponseFormatException() {} - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthClient.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthClient.java deleted file mode 100644 index 7ddb381..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthClient.java +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.util.JsonReader; - -import org.apache.http.client.HttpClient; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; - -import java.io.IOException; -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; - -/** - * Google authentication client. Fetches a pair of refresh/access tokens for a - * secret received while registering the instance in GCD. - */ -public class OAuthClient { - public static final String API_BASE = "https://accounts.google.com/o/oauth2"; - public static final String ENCODING = "UTF-8"; - public static final String CONTENT_TYPE = "application/x-www-form-urlencoded"; - - private final HttpClient mHttpClient; - private final String mScope; - private final String mClientId; - private final String mClientSecret; - - OAuthClient(HttpClient httpClient, String scope, String clientId, String clientSecret) { - assert httpClient != null; - assert scope != null; - assert clientId != null; - assert clientSecret != null; - - mHttpClient = httpClient; - mScope = scope; - mClientId = clientId; - mClientSecret = clientSecret; - } - - public OAuthResult authenticate(String secret) throws IOException { - final long startTimeMs = System.currentTimeMillis(); - - String content = - "client_id=" + urlEncode(mClientId) - + "&client_secret=" + urlEncode(mClientSecret) - + "&scope=" + urlEncode(mScope) - + "&code=" + urlEncode(secret) - + "&redirect_uri=oob" - + "&grant_type=authorization_code"; - - return mHttpClient.execute( - newHttpPost("/token", content), - new JsonResponseHandler() { - @Override - public OAuthResult readResponse(JsonReader reader) throws IOException { - return readResponse(reader, startTimeMs); - } - }); - } - - private HttpPost newHttpPost(String path, String content) throws UnsupportedEncodingException { - HttpPost request = new HttpPost(API_BASE + "/token"); - request.setEntity(new StringEntity(content, ENCODING)); - request.addHeader("Content-Type", CONTENT_TYPE); - return request; - } - - private static String urlEncode(String value) { - try { - return URLEncoder.encode(value, ENCODING); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } - - static OAuthResult readResponse(JsonReader reader, long startTimeMs) throws IOException { - String refreshToken = null; - String accessToken = null; - long expiresInS = 0; // In seconds. - - reader.beginObject(); - while (reader.hasNext()) { - String name = reader.nextName(); - if (name.equals("refresh_token")) { - refreshToken = reader.nextString(); - } else if (name.equals("access_token")) { - accessToken = reader.nextString(); - } else if (name.equals("expires_in")) { - expiresInS = reader.nextLong(); - } else { - reader.skipValue(); - } - } - reader.endObject(); - - return OAuthResult.create( - refreshToken, accessToken, startTimeMs + expiresInS * 1000); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthResult.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthResult.java deleted file mode 100644 index 3c9c5ac..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/apiary/OAuthResult.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -/** - * Pair of refresh/access tokens fetched with OAuthClient. - */ -public class OAuthResult { - public String refreshToken; - public String accessToken; - public final long expirationTimeMs; // In milliseconds. - - private OAuthResult(String refreshToken, String accessToken, long expirationTimeMs) { - assert refreshToken != null; - - this.refreshToken = refreshToken; - this.accessToken = accessToken; - this.expirationTimeMs = expirationTimeMs; - } - - public static OAuthResult create( - String refreshToken, String accessToken, long expirationTimeMs) { - return refreshToken != null - ? new OAuthResult(refreshToken, accessToken, expirationTimeMs) : null; - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Command.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Command.java deleted file mode 100644 index d71eacf..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Command.java +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import java.util.Map; - -/** - * Base class for a command. Command is an abstracton over GCD's command. Command - * has state, in- and out-parameters. Both parameters are encoded as a hash of strings. - */ -public abstract class Command { - public final Type type; - public final String id; - - private State mState = State.INITIAL; - private String mErrorMessage; - - public enum State { - INITIAL, DONE, ERROR - } - - public enum Type { - START_SESSION(Commands.StartSessionCommand.DEFINITION), - ICE_EXCHANGE(Commands.IceExchangeCommand.DEFINITION), - RENEGOTIATE(Commands.RenegotiateCommand.DEFINITION); - - public final CommandDefinition definition; - - Type(CommandDefinition definition) { - this.definition = definition; - } - } - - /** - * Provides access to parameters values with the Visitor pattern. - */ - public interface ParamVisitor { - void visit(ParamDefinition param, String value); - } - - protected Command(Type type, String id) { - assert type != null; - - this.type = type; - this.id = id; - } - - public State state() { - return mState; - } - - public abstract void visitInParams(ParamVisitor visitor); - - public abstract void visitOutParams(ParamVisitor visitor); - - protected abstract void setOutParams(Map actualOutParams) - throws CommandFormatException; - - protected final void setDone() { - assert mState == State.INITIAL; - - mState = State.DONE; - } - - public void setSuccess(Map actualOutParams) throws CommandFormatException { - setOutParams(actualOutParams); - setDone(); - } - - public void setFailure(String errorMessage) { - assert mState == State.INITIAL; - - mState = State.ERROR; - mErrorMessage = errorMessage; - } - - public String getErrorMessage() { - assert mState == State.ERROR; - - return mErrorMessage; - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandDefinition.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandDefinition.java deleted file mode 100644 index b7ddaf0..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandDefinition.java +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import java.util.List; -import java.util.Map; - -/** - * Definition for a Command and a command factory. Definition needed when - * registering in GCD. GCD only interested in in-parameters so to CommandDefinition. - */ -public abstract class CommandDefinition { - private final String mName; - private final List> mInParams; - - public CommandDefinition(String name, List> inParams) { - mName = name; - mInParams = inParams; - } - - public Iterable> inParams() { - return mInParams; - } - - public String shortName() { - return "_" + mName; - } - - public String fullName() { - return "base._" + mName; - } - - /** - * Factory method for creaiting a command from serialized state. - */ - public abstract Command newCommand(String id, Map actualParameters) - throws CommandFormatException; -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandFormatException.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandFormatException.java deleted file mode 100644 index 5054a3a..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandFormatException.java +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -/** - * This exception throws then a Command object cannot be reconstructed from serialized state. - */ -public class CommandFormatException extends Exception { - public CommandFormatException(String message) { - super(message); - } - - public CommandFormatException(String message, Exception cause) { - super(message, cause); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandReceiver.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandReceiver.java deleted file mode 100644 index 96672c7..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/CommandReceiver.java +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import org.chromium.components.devtools_bridge.SessionBase; -import org.chromium.components.devtools_bridge.SignalingReceiver; - -import java.util.List; - -/** - * Converts commands to SignalingReceiver's calls. - */ -public class CommandReceiver { - private final SignalingReceiver mBase; - - public CommandReceiver(SignalingReceiver base) { - mBase = base; - } - - public void receive(Command command, Runnable completionHandler) { - switch (command.type) { - case START_SESSION: - onCommand((Commands.StartSessionCommand) command, completionHandler); - break; - - case RENEGOTIATE: - onCommand((Commands.RenegotiateCommand) command, completionHandler); - break; - - case ICE_EXCHANGE: - onCommand((Commands.IceExchangeCommand) command, completionHandler); - break; - - default: - assert false; - } - } - - private void onCommand( - final Commands.StartSessionCommand command, final Runnable completionHandler) { - mBase.startSession( - command.sessionId, command.config, command.offer, - new SessionBase.NegotiationCallback() { - @Override - public void onSuccess(String answer) { - command.setResult(answer); - completionHandler.run(); - } - - @Override - public void onFailure(String errorMessage) { - command.setFailure(errorMessage); - completionHandler.run(); - } - }); - } - - private void onCommand( - final Commands.RenegotiateCommand command, final Runnable completionHandler) { - mBase.renegotiate( - command.sessionId, command.offer, - new SessionBase.NegotiationCallback() { - @Override - public void onSuccess(String answer) { - command.setResult(answer); - completionHandler.run(); - } - - @Override - public void onFailure(String errorMessage) { - command.setFailure(errorMessage); - completionHandler.run(); - } - }); - } - - private void onCommand( - final Commands.IceExchangeCommand command, final Runnable completionHandler) { - mBase.iceExchange( - command.sessionId, command.clientCandidates, - new SessionBase.IceExchangeCallback() { - @Override - public void onSuccess(List serverCandidates) { - command.setResult(serverCandidates); - completionHandler.run(); - } - - @Override - public void onFailure(String errorMessage) { - command.setFailure(errorMessage); - completionHandler.run(); - } - }); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Commands.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Commands.java deleted file mode 100644 index 2157078..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/Commands.java +++ /dev/null @@ -1,196 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import org.chromium.components.devtools_bridge.RTCConfiguration; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -/** - * Implementation of all commands. - */ -final class Commands { - public static final String NO_ID = null; - - // In params. - private static final ParamDefinition PARAM_SESSION_ID = - ParamDefinitions.newStringParam("sessionId"); - private static final ParamDefinition PARAM_CONFIG = - ParamDefinitions.newConfigParam("config"); - private static final ParamDefinition PARAM_OFFER = - ParamDefinitions.newStringParam("offer"); - private static final ParamDefinition> PARAM_CLIENT_CANDIDATES = - ParamDefinitions.newStringListParam("clientCandidates"); - - // Out params. - private static final ParamDefinition PARAM_ANSWER = - ParamDefinitions.newStringParam("answer"); - private static final ParamDefinition> PARAM_SERVER_CANDIDATES = - ParamDefinitions.newStringListParam("serverCandidates"); - - /** - * Common base class for signaling commands. All commands needed so far have a session ID - * and a single out parameter (result). - */ - abstract static class SignalingCommandBase extends Command { - public final String sessionId; - public R mResult; - - protected SignalingCommandBase(Type type, String id, String sessionId) { - super(type, id); - this.sessionId = sessionId; - } - - @Override - public void visitInParams(ParamVisitor visitor) { - PARAM_SESSION_ID.pass(visitor, sessionId); - } - - @Override - public final void visitOutParams(ParamVisitor visitor) { - resultDefinition().pass(visitor, mResult); - } - - @Override - protected void setOutParams(Map actualOutParams) - throws CommandFormatException { - mResult = resultDefinition().checkAndGet(actualOutParams); - } - - public final void setResult(R result) { - mResult = result; - setDone(); - } - - public final R getResult() { - assert state() == State.DONE; - return mResult; - } - - protected abstract ParamDefinition resultDefinition(); - } - - static final class StartSessionCommand extends SignalingCommandBase { - public final RTCConfiguration config; - public final String offer; - - public static final CommandDefinition DEFINITION = new CommandDefinition( - "startSession", params(PARAM_SESSION_ID, PARAM_CONFIG, PARAM_OFFER)) { - @Override - public Command newCommand(String id, Map actualParameters) - throws CommandFormatException { - return new StartSessionCommand( - id, - PARAM_SESSION_ID.get(actualParameters), - PARAM_CONFIG.get(actualParameters), - PARAM_OFFER.get(actualParameters)); - } - }; - - private StartSessionCommand( - String id, String sessionId, RTCConfiguration config, String offer) { - super(Type.START_SESSION, id, sessionId); - this.config = config; - this.offer = offer; - } - - public StartSessionCommand(String sessionId, RTCConfiguration config, String offer) { - this(NO_ID, sessionId, config, offer); - } - - @Override - public void visitInParams(ParamVisitor visitor) { - super.visitInParams(visitor); - PARAM_CONFIG.pass(visitor, config); - PARAM_OFFER.pass(visitor, offer); - } - - @Override - protected ParamDefinition resultDefinition() { - return PARAM_ANSWER; - } - } - - static final class IceExchangeCommand extends SignalingCommandBase> { - private static final String SERVER_CANDIDATES = "serverCandidates"; - - public final List clientCandidates; - - public static final CommandDefinition DEFINITION = new CommandDefinition( - "iceExchange", params(PARAM_SESSION_ID, PARAM_CLIENT_CANDIDATES)) { - @Override - public Command newCommand(String id, Map actualParameters) - throws CommandFormatException { - return new IceExchangeCommand( - id, - PARAM_SESSION_ID.get(actualParameters), - PARAM_CLIENT_CANDIDATES.get(actualParameters)); - } - }; - - private IceExchangeCommand(String id, String sessionId, List clientCandidates) { - super(Type.ICE_EXCHANGE, id, sessionId); - this.clientCandidates = clientCandidates; - } - - public IceExchangeCommand(String sessionId, List clientCandidates) { - this(NO_ID, sessionId, clientCandidates); - } - - @Override - public void visitInParams(ParamVisitor visitor) { - super.visitInParams(visitor); - PARAM_CLIENT_CANDIDATES.pass(visitor, clientCandidates); - } - - @Override - protected ParamDefinition> resultDefinition() { - return PARAM_SERVER_CANDIDATES; - } - } - - static final class RenegotiateCommand extends SignalingCommandBase { - public final String offer; - - public static final CommandDefinition DEFINITION = new CommandDefinition( - "renegotiate", params(PARAM_SESSION_ID, PARAM_OFFER)) { - @Override - public Command newCommand(String id, Map actualParameters) - throws CommandFormatException { - return new RenegotiateCommand( - id, - PARAM_SESSION_ID.get(actualParameters), - PARAM_OFFER.get(actualParameters)); - } - }; - - private RenegotiateCommand(String id, String sessionId, String offer) { - super(Type.RENEGOTIATE, id, sessionId); - this.offer = offer; - } - - public RenegotiateCommand(String sessionId, String offer) { - this(NO_ID, sessionId, offer); - } - - @Override - public void visitInParams(ParamVisitor visitor) { - super.visitInParams(visitor); - PARAM_OFFER.pass(visitor, offer); - } - - @Override - protected ParamDefinition resultDefinition() { - return PARAM_ANSWER; - } - } - - private static List> params(ParamDefinition... values) { - return Collections.unmodifiableList(Arrays.asList(values)); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinition.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinition.java deleted file mode 100644 index 07fd314..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinition.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import java.util.Map; - -/** - * Desribes in- or out-parameter of a Command. - * @param Type of the parameter. - */ -public abstract class ParamDefinition { - public final String mName; - - protected ParamDefinition(String name) { - mName = name; - } - - public String name() { - return "_" + mName; - } - - public String type() { - return "string"; - } - - public void checkPresents(Map actualParameters) throws CommandFormatException { - if (!actualParameters.containsKey(name())) { - throw new CommandFormatException("Missing parameter " + mName); - } - } - - public T get(Map actualParameters) throws CommandFormatException { - return fromString(actualParameters.get(name())); - } - - public T checkAndGet(Map actualParameters) throws CommandFormatException { - checkPresents(actualParameters); - return get(actualParameters); - } - - public final void pass(Command.ParamVisitor visitor, T value) { - visitor.visit(this, toString(value)); - } - - protected abstract T fromString(String value) throws CommandFormatException; - protected abstract String toString(T value); -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinitions.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinitions.java deleted file mode 100644 index c2b0446..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/commands/ParamDefinitions.java +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import android.util.JsonReader; -import android.util.JsonWriter; - -import org.chromium.components.devtools_bridge.RTCConfiguration; - -import java.io.IOException; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.ArrayList; -import java.util.List; - -/** - * Hepler class with a collection of parameter definitions. - */ -final class ParamDefinitions { - public static ParamDefinition newStringParam(String name) { - return new ParamDefinition(name) { - @Override - protected String fromString(String value) { - return value; - } - - @Override - protected String toString(String value) { - return value; - } - }; - } - - public static ParamDefinition> newStringListParam(String name) { - return new ParamDefinition>(name) { - @Override - protected List fromString(String value) throws CommandFormatException { - try { - return new ParamReader(value) - .readStringList() - .close() - .stringListResult; - } catch (Exception e) { - throw newException(this, "Expected JSON-serialized string list", e); - } - } - - @Override - protected String toString(List value) { - try { - return new ParamWriter().write(value).close().toString(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }; - } - - public static ParamDefinition newConfigParam(String name) { - return new ParamDefinition(name) { - @Override - protected RTCConfiguration fromString(String value) throws CommandFormatException { - try { - return new ParamReader(value) - .readConfig() - .close() - .configResult; - } catch (Exception e) { - throw newException(this, "Expected WebRTC configuration", e); - } - } - - @Override - protected String toString(RTCConfiguration value) { - try { - return new ParamWriter().write(value).close().toString(); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - }; - } - - private static CommandFormatException newException( - ParamDefinition param, String message, Exception cause) { - return new CommandFormatException( - "Exception in parameter " + param.name() + ": " + message, cause); - } - - private static class ParamReader { - private final JsonReader mReader; - - public List stringListResult; - public RTCConfiguration configResult; - - public ParamReader(String source) { - mReader = new JsonReader(new StringReader(source)); - } - - public ParamReader readStringList() throws IOException { - stringListResult = new ArrayList(); - mReader.beginArray(); - while (mReader.hasNext()) { - stringListResult.add(mReader.nextString()); - } - mReader.endArray(); - return this; - } - - public ParamReader readConfig() throws IOException { - RTCConfiguration.Builder builder = new RTCConfiguration.Builder(); - mReader.beginObject(); - while (mReader.hasNext()) { - String name = mReader.nextName(); - if ("iceServers".equals(name)) { - readIceServerList(builder); - } else { - mReader.skipValue(); - } - } - configResult = builder.build(); - return this; - } - - public ParamReader close() throws IOException { - mReader.close(); - return this; - } - - private void readIceServerList(RTCConfiguration.Builder builder) throws IOException { - mReader.beginArray(); - while (mReader.hasNext()) { - readIceServer(builder); - } - mReader.endArray(); - } - - private void readIceServer(RTCConfiguration.Builder builder) throws IOException { - String uri = null; - String username = ""; - String credential = ""; - mReader.beginObject(); - while (mReader.hasNext()) { - String name = mReader.nextName(); - if ("uri".equals(name)) { - uri = mReader.nextString(); - } else if ("username".equals(name)) { - username = mReader.nextString(); - } else if ("credential".equals(name)) { - credential = mReader.nextString(); - } else { - mReader.skipValue(); - } - } - mReader.endObject(); - if (uri != null) { - builder.addIceServer(uri, username, credential); - } - } - } - - private static class ParamWriter { - private final StringWriter mStringWriter = new StringWriter(); - private final JsonWriter mWriter = new JsonWriter(mStringWriter); - - public ParamWriter write(List value) throws IOException { - mWriter.beginArray(); - for (String item : value) { - mWriter.value(item); - } - mWriter.endArray(); - return this; - } - - public ParamWriter write(RTCConfiguration config) throws IOException { - mWriter.beginObject(); - mWriter.name("iceServers"); - mWriter.beginArray(); - for (RTCConfiguration.IceServer server : config.iceServers) { - mWriter.beginObject(); - mWriter.name("uri").value(server.uri); - mWriter.name("username").value(server.username); - mWriter.name("credential").value(server.credential); - mWriter.endObject(); - } - mWriter.endArray(); - mWriter.endObject(); - return this; - } - - public ParamWriter close() throws IOException { - mWriter.close(); - return this; - } - - @Override - public String toString() { - return mStringWriter.toString(); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceCredential.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceCredential.java deleted file mode 100644 index 7edb807..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceCredential.java +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -import android.content.SharedPreferences; - -/** - * Information provided by GCD when instance has registered. Instance id - * can be used for: - * 1. Making sure incoming messages are addressed to the instance. - * 2. It needed when sending command results to GCD. - * 3. For device unregistration. - * - * The Secret supposed to be used to authenticate the instance with OAuthClient - * (it has no user credentials). - */ -public final class InstanceCredential { - public static final String PREF_ID = "gcd.ID"; - public static final String PREF_SECRET = "gcd.SECRET"; - - public final String id; - public final String secret; - - public InstanceCredential(String id, String secret) { - assert id != null; - assert secret != null; - - this.id = id; - this.secret = secret; - } - - public static InstanceCredential get(SharedPreferences preferences) { - String id = preferences.getString(PREF_ID, null); - String secret = preferences.getString(PREF_SECRET, null); - return id != null && secret != null ? new InstanceCredential(id, secret) : null; - } - - public void put(SharedPreferences.Editor editor) { - editor.putString(PREF_ID, id); - editor.putString(PREF_SECRET, secret); - } - - public static void remove(SharedPreferences.Editor editor) { - editor.remove(PREF_ID); - editor.remove(PREF_SECRET); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceDescription.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceDescription.java deleted file mode 100644 index 6d740bb..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/InstanceDescription.java +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -/** - * Information needed for registration in GCD. - * Instance secret will be bound to oAuthClientId. - * gcmChannelId will be used for delivering commands. - * displayName is a human readable name on the client side. - */ -public final class InstanceDescription { - public final String oAuthClientId; - public final String gcmChannelId; - public final String displayName; - - private InstanceDescription(String oAuthClientId, String gcmChannelId, String displayName) { - assert oAuthClientId != null; - assert gcmChannelId != null; - assert displayName != null; - - this.oAuthClientId = oAuthClientId; - this.gcmChannelId = gcmChannelId; - this.displayName = displayName; - } - - /** - * Builder for InstanceDescription. - */ - public static final class Builder { - private String mOAuthClientId; - private String mGCMChannelId; - private String mDisplayName; - - public Builder setOAuthClientId(String value) { - mOAuthClientId = value; - return this; - } - - public Builder setGCMChannelId(String value) { - mGCMChannelId = value; - return this; - } - - public Builder setDisplayName(String value) { - mDisplayName = value; - return this; - } - - public InstanceDescription build() { - return new InstanceDescription(mOAuthClientId, mGCMChannelId, mDisplayName); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageReader.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageReader.java deleted file mode 100644 index 87c61f6..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageReader.java +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -import android.util.JsonReader; - -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.commands.CommandFormatException; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -/** - * Helper class for parsing JSON-encoded GCD messages (HTTP responses and GCM notifications) used - * in the DevTools bridge. - */ -public final class MessageReader { - private final JsonReader mReader; - - public MessageReader(JsonReader reader) { - mReader = reader; - } - - /** - * Reads id from a registration ticket. - */ - public String readTicketId() throws IOException { - return new TicketReader().readId(); - } - - /** - * Reads credentials from finalized registration ticket. - */ - public InstanceCredential readInstanceCredential() throws IOException { - return new TicketReader().readCredential(); - } - - Notification readNotification() throws IOException, CommandFormatException { - return new NotificationReader().read(); - } - - private abstract class ObjectReader { - public final void readObject() throws IOException { - mReader.beginObject(); - while (mReader.hasNext()) { - readItem(mReader.nextName()); - } - mReader.endObject(); - } - - protected void readItem(String name) throws IOException { - mReader.skipValue(); - } - } - - private class TicketReader extends ObjectReader { - private String mId; - private String mDeviceId; - private String mDeviceSecret; - - public String readId() throws IOException { - readObject(); - if (mId == null) { - throw new IllegalArgumentException(); - } - return mId; - } - - public InstanceCredential readCredential() throws IOException { - readObject(); - if (mDeviceId == null || mDeviceSecret == null) { - throw new IllegalArgumentException(); - } - return new InstanceCredential(mDeviceId, mDeviceSecret); - } - - @Override - protected void readItem(String name) throws IOException { - if (name.equals("id")) { - mId = mReader.nextString(); - } else if (name.equals("deviceId")) { - mDeviceId = mReader.nextString(); - } else if (name.equals("robotAccountAuthorizationCode")) { - mDeviceSecret = mReader.nextString(); - } else { - super.readItem(name); - } - } - } - - private class NotificationReader extends ObjectReader { - private String mDeviceId; - private String mType; - private String mCommandId; - private CommandReader mCommandReader; - - public Notification read() throws IOException, CommandFormatException { - readObject(); - if (mDeviceId == null || mType == null) return null; - if (mType.equals("COMMAND_CREATED")) { - if (mCommandReader == null) { - throw new CommandFormatException("Command missing"); - } - if (mCommandId == null) { - throw new CommandFormatException("Command id missing"); - } - return new Notification( - mDeviceId, Notification.Type.COMMAND_CREATED, - mCommandReader.newCommand(mCommandId)); - } else if (mType.equals("DEVICE_DELETED")) { - return new Notification(mDeviceId, Notification.Type.INSTANCE_UNREGISTERED, null); - } else { - return null; - } - } - - @Override - protected void readItem(String name) throws IOException { - if (name.equals("deviceId")) { - mDeviceId = mReader.nextString(); - } else if (name.equals("type")) { - mType = mReader.nextString(); - } else if (name.equals("commandId")) { - mCommandId = mReader.nextString(); - } else if (name.equals("command")) { - mCommandReader = new CommandReader(); - mCommandReader.readObject(); - } else { - super.readItem(name); - } - } - } - - private class CommandReader extends ObjectReader { - private String mType; - private Map mParameters; - - public Command newCommand(String id) throws CommandFormatException { - if (mType == null) { - throw new CommandFormatException("Missing command type"); - } - if (mParameters == null) { - throw new CommandFormatException("Missing parameters"); - } - return convertType(mType).definition.newCommand(id, mParameters); - } - - @Override - protected void readItem(String name) throws IOException { - if (name.equals("name")) { - mType = mReader.nextString(); - } else if (name.equals("parameters")) { - mParameters = readStringMap(mReader); - } else { - super.readItem(name); - } - } - - private Command.Type convertType(String name) throws CommandFormatException { - for (Command.Type type : Command.Type.values()) { - if (type.definition.fullName().equals(name)) return type; - } - throw new CommandFormatException("Invalid type: " + name); - } - } - - static Map readStringMap(JsonReader reader) throws IOException { - Map result = new HashMap(); - reader.beginObject(); - while (reader.hasNext()) { - String name = reader.nextName(); - String value = reader.nextString(); - result.put(name, value); - } - reader.endObject(); - return result; - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageWriter.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageWriter.java deleted file mode 100644 index 2d7388f..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/MessageWriter.java +++ /dev/null @@ -1,156 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -import android.util.JsonWriter; - -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.commands.ParamDefinition; - -import java.io.IOException; -import java.io.StringWriter; - -/** - * Helper class for constructing GCD JSON messages (HTTP requests) used in the DevTools bridge. - */ -public final class MessageWriter { - private final StringWriter mStringWriter; - private final JsonWriter mWriter; - boolean mClosed = false; - - public MessageWriter() { - mStringWriter = new StringWriter(); - mWriter = new JsonWriter(mStringWriter); - } - - public MessageWriter close() throws IOException { - assert !mClosed; - mWriter.close(); - mClosed = true; - return this; - } - - @Override - public String toString() { - assert mClosed; - return mStringWriter.toString(); - } - - /** - * Writes body of registrationTicket PATCH request. - */ - public MessageWriter writeTicketPatch(InstanceDescription description) throws IOException { - mWriter.beginObject(); - mWriter.name("deviceDraft"); - writeDeviceDraft(description); - mWriter.name("oauthClientId").value(description.oAuthClientId); - mWriter.endObject(); - return this; - } - - /** - * Writes body of devices/ PATCH request. - */ - public MessageWriter writeDeviceGCMChannelPatch(String gcmChannelId) throws IOException { - mWriter.beginObject(); - mWriter.name("channel"); - mWriter.beginObject(); - mWriter.name("gcmRegistrationId").value(gcmChannelId); - mWriter.endObject(); - mWriter.endObject(); - return this; - } - - private void writeDeviceDraft(InstanceDescription description) throws IOException { - mWriter.beginObject(); - mWriter.name("deviceKind").value("vendor"); - mWriter.name("displayName").value(description.displayName); - mWriter.name("systemName").value("Chrome DevTools Bridge"); - mWriter.name("channel"); - writeChannelDefinition(description); - mWriter.name("commandDefs"); - writeCommandsDefinition(); - mWriter.endObject(); - } - - private void writeChannelDefinition(InstanceDescription description) throws IOException { - mWriter.beginObject(); - mWriter.name("supportedType").value("gcm"); - mWriter.name("gcmRegistrationId").value(description.gcmChannelId); - mWriter.endObject(); - } - - private void writeCommandsDefinition() throws IOException { - mWriter.beginObject(); - mWriter.name("base"); - writeCommandsDefinitionBase(); - mWriter.endObject(); - } - - private void writeCommandsDefinitionBase() throws IOException { - mWriter.beginObject(); - for (Command.Type type : Command.Type.values()) { - mWriter.name(type.definition.shortName()); - beginParameters(); - for (ParamDefinition param : type.definition.inParams()) { - writeParameter(param.name(), param.type()); - } - endParameters(); - } - mWriter.endObject(); - } - - private void beginParameters() throws IOException { - mWriter.beginObject(); - mWriter.name("parameters"); - mWriter.beginObject(); - } - - private void endParameters() throws IOException { - mWriter.endObject(); - mWriter.endObject(); - } - - private void writeParameter(String name, String type) throws IOException { - mWriter.name(name); - mWriter.beginObject(); - mWriter.name("type").value(type); - mWriter.endObject(); - } - - /** - * Writes body of command PATCH request. Updates command status and out parametes - * when the command has processed. - */ - public MessageWriter writeCommandPatch(Command command) throws IOException { - mWriter.beginObject(); - if (command.state() == Command.State.DONE) { - mWriter.name("state").value("done"); - mWriter.name("results"); - mWriter.beginObject(); - command.visitOutParams(new ParamWriter()); - mWriter.endObject(); - } else if (command.state() == Command.State.ERROR) { - mWriter.name("state").value("error"); - mWriter.name("error"); - mWriter.beginObject(); - mWriter.name("message").value(command.getErrorMessage()); - mWriter.endObject(); - } - mWriter.endObject(); - return this; - } - - private class ParamWriter implements Command.ParamVisitor { - @Override - public void visit(ParamDefinition param, String value) { - try { - mWriter.name(param.name()).value(value); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/Notification.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/Notification.java deleted file mode 100644 index e8899f4..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/gcd/Notification.java +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -import android.util.JsonReader; - -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.commands.CommandFormatException; - -import java.io.IOException; -import java.io.StringReader; - -/** - * Notification that GCD sends to an instance. - */ -public final class Notification { - public final String instanceId; - public final Type type; - public final Command command; - - public enum Type { - COMMAND_CREATED, // Command created and needs to be executed. - INSTANCE_UNREGISTERED // Instance unregistered (possibly through external UI). - } - - Notification(String instanceId, Type type, Command command) { - this.instanceId = instanceId; - this.type = type; - this.command = command; - } - - public static Notification read(String source) throws FormatException { - JsonReader reader = new JsonReader(new StringReader(source)); - try { - Notification result = new MessageReader(reader).readNotification(); - reader.close(); - return result; - } catch (CommandFormatException e) { - throw new FormatException(e); - } catch (IllegalStateException e) { - throw new FormatException(e); - } catch (IllegalArgumentException e) { - throw new FormatException(e); - } catch (IOException e) { - throw new RuntimeException(e); - } - } - - /** - * Exception when parsing notification. - */ - public static class FormatException extends Exception { - public FormatException(RuntimeException cause) { - super(cause); - } - - public FormatException(CommandFormatException cause) { - super(cause); - } - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java deleted file mode 100644 index 09989b3..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/ui/GCDRegistrationFragment.java +++ /dev/null @@ -1,320 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.ui; - -import android.accounts.Account; -import android.accounts.AccountManager; -import android.accounts.AccountManagerCallback; -import android.accounts.AccountManagerFuture; -import android.app.Activity; -import android.app.Fragment; -import android.app.ProgressDialog; -import android.content.Context; -import android.content.DialogInterface; -import android.content.Intent; -import android.content.SharedPreferences; -import android.os.AsyncTask; -import android.os.Bundle; -import android.util.Log; -import android.widget.Toast; - -import org.chromium.components.devtools_bridge.DevToolsBridgeServer; -import org.chromium.components.devtools_bridge.apiary.ApiaryClientFactory; -import org.chromium.components.devtools_bridge.apiary.OAuthResult; -import org.chromium.components.devtools_bridge.gcd.InstanceCredential; -import org.chromium.components.devtools_bridge.gcd.InstanceDescription; - -import java.io.IOException; - -/** - * Fragment that responsible for: - * 1. Displaying GCD registration status. - * 2. Instance registration. - * 3. Instance unregistration. - * - * Fragment is abstract and does not provide UI controls. Descendant is responsible for it. - * It also should have actionable item for registration/unregistration which invokes - * appropriate methods. - */ -public abstract class GCDRegistrationFragment extends Fragment - implements SharedPreferences.OnSharedPreferenceChangeListener { - private static final String TAG = "GCDRegistrationFragment"; - private static final String PREF_OWNER_EMAIL = "ui.OWNER_EMAIL"; - private static final String PREF_DISPLAY_NAME = "ui.OWNER_EMAIL"; - private static final int CODE_ACCOUNT_SELECTED = 1; - - private ApiaryClientFactory mClientFactory; - private Account mSelectedAccount = null; - - private SharedPreferences mPreferences; - - private InstanceCredential mInstanceCredential; - - @Override - public void onCreate(Bundle savedInstanceState) { - mClientFactory = new ApiaryClientFactory(); - mPreferences = DevToolsBridgeServer.getPreferences(getActivity()); - mPreferences.registerOnSharedPreferenceChangeListener(this); - mInstanceCredential = InstanceCredential.get(mPreferences); - super.onCreate(savedInstanceState); - } - - @Override - public void onDestroy() { - super.onDestroy(); - mPreferences.unregisterOnSharedPreferenceChangeListener(this); - new AsyncTask() { - @Override - protected final Void doInBackground(Void... args) { - mClientFactory.close(); - return null; - } - }.execute(); - } - - @Override - public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { - if (key.equals(InstanceCredential.PREF_ID)) { - mInstanceCredential = InstanceCredential.get(mPreferences); - onRegistrationStatusChange(); - } - } - - public void register() { - AccountManager manager = AccountManager.get(getActivity()); - - Intent intent = manager.newChooseAccountIntent( - mSelectedAccount, - null /* allowableAccounts */, - new String[] { "com.google" } /* allowableAccountTypes */, - true /* alwaysPromptForAccount */, - "Registration in GCD" /* descriptionOverrideText */, - null /* addAccountAuthTokenType */, - null /* addAccountRequiredFeatures */, - null /* addAccountOptions */); - startActivityForResult(intent, CODE_ACCOUNT_SELECTED); - } - - public void unregister() { - if (mInstanceCredential == null) return; - - new RegistrationTask("Unregistering instance") { - private InstanceCredential mInstranceCredentialCopy = mInstanceCredential; - - @Override - protected void doInBackgroundImpl() throws IOException, InterruptedException { - OAuthResult result = mClientFactory.newOAuthClient() - .authenticate(mInstranceCredentialCopy.secret); - - checkInterrupted(); - - Log.d(TAG, "Access token: " + result.accessToken); - - mClientFactory.newGCDClient(result.accessToken) - .deleteInstance(mInstranceCredentialCopy.id); - } - - @Override - protected void onSuccess() { - saveRegistration(null, null, null); - onRegistrationStatusChange(); - showToast("Unregistered"); - } - - @Override - protected void onFailure(Exception e) { - Log.e(TAG, "Unregistration failed", e); - showToast("Unregistration failed. See log for details."); - } - }.execute(); - } - - public boolean isRegistered() { - return mInstanceCredential != null; - } - - public String getOwner() { - return mPreferences.getString(PREF_OWNER_EMAIL, ""); - } - - public String getDisplayName() { - return mPreferences.getString(PREF_DISPLAY_NAME, ""); - } - - public void queryOAuthToken() { - if (mSelectedAccount == null) return; - - AccountManager manager = AccountManager.get(getActivity()); - - final String ownerEmail = mSelectedAccount.name; - - manager.getAuthToken( - mSelectedAccount, - "oauth2:" + ApiaryClientFactory.OAUTH_SCOPE, null /* options */, getActivity(), - new AccountManagerCallback() { - @Override - public void run(AccountManagerFuture future) { - try { - String token = future.getResult().getString( - AccountManager.KEY_AUTHTOKEN); - register(ownerEmail, token); - } catch (Exception e) { - Log.e(TAG, "Failed to get token: ", e); - } - } - }, null); - } - - private void register(final String ownerEmail, final String oAuthToken) { - new RegistrationTask("Registering instance") { - private Context mContext; - - private String mDisplayName; - private InstanceDescription mDescription; - private InstanceCredential mCredential; - - @Override - protected void onPreExecute() { - mContext = getActivity(); - - mDisplayName = generateDisplayName(); - super.onPreExecute(); - } - - @Override - protected void doInBackgroundImpl() throws IOException, InterruptedException { - String ticketId = mClientFactory.newGCDClient(oAuthToken) - .createRegistrationTicket(); - - checkInterrupted(); - - String gcmChannelId = - mClientFactory.newGCMRegistrar().blockingGetRegistrationId(mContext); - - mDescription = new InstanceDescription.Builder() - .setOAuthClientId(mClientFactory.getOAuthClientId()) - .setGCMChannelId(gcmChannelId) - .setDisplayName(mDisplayName) - .build(); - - mClientFactory.newAnonymousGCDClient().patchRegistrationTicket( - ticketId, mDescription); - - checkInterrupted(); - - mCredential = mClientFactory.newAnonymousGCDClient().finalizeRegistration(ticketId); - } - - @Override - protected void onSuccess() { - saveRegistration(mDescription, mCredential, ownerEmail); - onRegistrationStatusChange(); - showToast("Registered"); - } - - @Override - protected void onFailure(Exception e) { - Log.e(TAG, "Registration failed", e); - showToast("Registration failed. See log for details."); - } - }.execute(); - } - - @Override - public void onActivityResult(final int requestCode, final int resultCode, final Intent data) { - if (requestCode == CODE_ACCOUNT_SELECTED && resultCode == Activity.RESULT_OK) { - mSelectedAccount = new Account( - data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME), - data.getStringExtra(AccountManager.KEY_ACCOUNT_TYPE)); - Log.d(TAG, "Selected account=" + mSelectedAccount); - queryOAuthToken(); - } - } - - private void saveRegistration( - InstanceDescription description, InstanceCredential credential, String ownerEmail) { - // TODO(serya): Make registration persistant. - mInstanceCredential = credential; - - SharedPreferences.Editor editor = mPreferences.edit(); - if (description != null && credential != null && ownerEmail != null) { - credential.put(editor); - editor.putString(PREF_DISPLAY_NAME, description.displayName); - editor.putString(PREF_OWNER_EMAIL, ownerEmail); - } else { - InstanceCredential.remove(editor); - editor.remove(PREF_DISPLAY_NAME); - editor.remove(PREF_OWNER_EMAIL); - } - editor.commit(); - } - - protected abstract void onRegistrationStatusChange(); - protected abstract String generateDisplayName(); - - private abstract class RegistrationTask extends AsyncTask { - private ProgressDialog mDialog; - private Exception mException; - - private final String mProgressMessage; - - protected RegistrationTask(String progressMessage) { - mProgressMessage = progressMessage; - } - - @Override - protected void onPreExecute() { - mDialog = ProgressDialog.show( - getActivity(), - "GCD registration", - mProgressMessage, - true, - false, - new DialogInterface.OnCancelListener() { - @Override - public void onCancel(DialogInterface dialog) { - cancel(true); - } - }); - } - - @Override - protected final Boolean doInBackground(Void... args) { - try { - doInBackgroundImpl(); - return Boolean.TRUE; - } catch (IOException e) { - mException = e; - } catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - return Boolean.FALSE; - } - - protected final void checkInterrupted() throws InterruptedException { - if (Thread.currentThread().isInterrupted()) { - throw new InterruptedException(); - } - } - - @Override - protected void onPostExecute(Boolean success) { - mDialog.dismiss(); - if (Boolean.TRUE.equals(success)) { - onSuccess(); - } else if (mException != null) { - onFailure(mException); - } - } - - protected void showToast(String message) { - Toast.makeText(getActivity(), message, Toast.LENGTH_SHORT).show(); - } - - protected abstract void doInBackgroundImpl() throws IOException, InterruptedException; - protected abstract void onSuccess(); - protected abstract void onFailure(Exception e); - } -} diff --git a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/util/LooperExecutor.java b/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/util/LooperExecutor.java deleted file mode 100644 index ce383be..0000000 --- a/components/devtools_bridge/android/java/src/org/chromium/components/devtools_bridge/util/LooperExecutor.java +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.util; - -import android.content.Context; -import android.os.Handler; - -import org.chromium.components.devtools_bridge.SessionBase; - -/** - * Implementation of SessionBase.Executor on top of android's handler. - */ -public class LooperExecutor implements SessionBase.Executor { - private final Handler mHandler; - - public LooperExecutor(Handler handler) { - mHandler = handler; - } - - public static LooperExecutor newInstanceForMainLooper(Context context) { - return new LooperExecutor(new Handler(context.getMainLooper())); - } - - @Override - public SessionBase.Cancellable postOnSessionThread(int delayMs, Runnable runnable) { - CancellableTask task = new CancellableTask(runnable); - mHandler.postDelayed(task, delayMs); - return task; - } - - @Override - public boolean isCalledOnSessionThread() { - return mHandler.getLooper().getThread() == Thread.currentThread(); - } - - private final class CancellableTask implements SessionBase.Cancellable, Runnable { - private Runnable mTask; - - public CancellableTask(Runnable task) { - mTask = task; - } - - @Override - public void run() { - if (mTask != null) mTask.run(); - } - - @Override - public void cancel() { - mHandler.removeCallbacks(this); - mTask = null; - } - } -} diff --git a/components/devtools_bridge/android/javatests/AndroidManifest.xml b/components/devtools_bridge/android/javatests/AndroidManifest.xml deleted file mode 100644 index c4671eb..0000000 --- a/components/devtools_bridge/android/javatests/AndroidManifest.xml +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/DevToolsBridgeServerTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/DevToolsBridgeServerTest.java deleted file mode 100644 index 9f1910a..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/DevToolsBridgeServerTest.java +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.content.Context; -import android.net.LocalServerSocket; -import android.net.LocalSocket; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.util.LooperExecutor; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.Future; - -/** - * Tests for {@link DevToolsBridgeServer} - */ -public class DevToolsBridgeServerTest extends InstrumentationTestCase { - private static final String REQUEST = "Request"; - private static final String RESPONSE = "Response"; - private static final String SESSION_ID = "SESSION_ID"; - private static final String CLIENT_SOCKET_NAME = - DevToolsBridgeServerTest.class.getName() + ".CLIENT_SOCKET_NAME"; - private static final String SERVER_SOCKET_NAME = - DevToolsBridgeServerTest.class.getName() + ".SERVER_SOCKET_NAME"; - private SessionDependencyFactory mFactory; - - private LooperExecutor mServerExecutor; - private DevToolsBridgeServer mServer; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mFactory = SessionDependencyFactory.newInstance(); - mServer = new DevToolsBridgeServer(new ServerDelegate()); - mServerExecutor = LooperExecutor.newInstanceForMainLooper( - getInstrumentation().getTargetContext()); - } - - @Override - protected void tearDown() throws Exception { - final CountDownLatch done = new CountDownLatch(1); - mServerExecutor.postOnSessionThread(0, new Runnable() { - @Override - public void run() { - mServer.dispose(); - mServer = null; - done.countDown(); - } - }); - done.await(); - mFactory.dispose(); - super.tearDown(); - } - - @SmallTest - public void testRequestResponse() throws Exception { - LocalServerSocket serverListeningSocket = new LocalServerSocket(SERVER_SOCKET_NAME); - ClientSessionTestingHost clientSession = new ClientSessionTestingHost( - mFactory, mServer, mServerExecutor, SESSION_ID, CLIENT_SOCKET_NAME); - clientSession.start(); - - Future response = TestUtils.asyncRequest(CLIENT_SOCKET_NAME, REQUEST); - LocalSocket serverSocket = serverListeningSocket.accept(); - String request = TestUtils.read(serverSocket, REQUEST.length()); - Assert.assertEquals(REQUEST, request); - TestUtils.write(serverSocket, RESPONSE); - serverSocket.close(); - Assert.assertEquals(RESPONSE, response.get()); - - clientSession.dispose(); - } - - private class ServerDelegate implements DevToolsBridgeServer.Delegate { - @Override - public Context getContext() { - return getInstrumentation().getTargetContext(); - } - - @Override - public void querySocketName(DevToolsBridgeServer.QuerySocketCallback callback) { - callback.onSuccess(SERVER_SOCKET_NAME); - } - - @Override - public void onSessionCountChange(int count) {} - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/LocalSessionBridgeTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/LocalSessionBridgeTest.java deleted file mode 100644 index 358702c..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/LocalSessionBridgeTest.java +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.net.LocalServerSocket; -import android.net.LocalSocket; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import junit.framework.Assert; - -import java.util.concurrent.Future; - -/** - * Tests for both client and server sessions bound with {@link LocalSessionBridge}. - */ -public class LocalSessionBridgeTest extends InstrumentationTestCase { - private static final String SERVER_SOCKET_NAME = - LocalSessionBridgeTest.class.getName() + ".SERVER_SOCKET"; - private static final String CLIENT_SOCKET_NAME = - LocalSessionBridgeTest.class.getName() + ".CLIENT_SOCKET"; - - private static final String REQUEST = "Request"; - private static final String RESPONSE = "Response"; - - private LocalSessionBridge mBridge; - - @Override - public void setUp() throws Exception { - super.setUp(); - mBridge = new LocalSessionBridge(SERVER_SOCKET_NAME, CLIENT_SOCKET_NAME); - } - - @Override - public void tearDown() throws Exception { - mBridge.dispose(); - super.tearDown(); - } - - @MediumTest - public void testDisposeAfeterStart() { - mBridge.start(); - } - - @MediumTest - public void testNegotiating() throws InterruptedException { - mBridge.start(); - mBridge.awaitNegotiated(); - } - - @MediumTest - public void testOpenControlChannel() throws InterruptedException { - mBridge.start(); - mBridge.awaitControlChannelOpened(); - } - - @MediumTest - public void testClientAutocloseTimeout() throws InterruptedException { - mBridge.setMessageDeliveryDelayMs(1000); - mBridge.setClientAutoCloseTimeoutMs(100); - mBridge.start(); - mBridge.awaitClientAutoClosed(); - } - - @MediumTest - public void testServerAutocloseTimeout() throws InterruptedException { - mBridge.setMessageDeliveryDelayMs(1000); - mBridge.setServerAutoCloseTimeoutMs(100); - mBridge.start(); - mBridge.awaitServerAutoClosed(); - } - - @MediumTest - public void testRequestResponse() throws Exception { - mBridge.start(); - - LocalServerSocket serverListeningSocket = new LocalServerSocket(SERVER_SOCKET_NAME); - Future response = TestUtils.asyncRequest(CLIENT_SOCKET_NAME, REQUEST); - LocalSocket serverSocket = serverListeningSocket.accept(); - String request = TestUtils.read(serverSocket, REQUEST.length()); - Assert.assertEquals(REQUEST, request); - TestUtils.write(serverSocket, RESPONSE); - serverSocket.close(); - Assert.assertEquals(RESPONSE, response.get()); - } - - @MediumTest - public void testRequestFailure1() throws Exception { - mBridge.start(); - LocalServerSocket serverListeningSocket = new LocalServerSocket(SERVER_SOCKET_NAME); - Future response = TestUtils.asyncRequest(CLIENT_SOCKET_NAME, REQUEST); - LocalSocket socket = serverListeningSocket.accept(); - int firstByte = socket.getInputStream().read(); - - Assert.assertEquals((int) REQUEST.charAt(0), firstByte); - - socket.close(); - Assert.assertEquals("", response.get()); - } - - @MediumTest - public void testRequestFailure2() throws Exception { - mBridge.dispose(); - // Android system socket will reject connection. - mBridge = new LocalSessionBridge("jdwp-control", CLIENT_SOCKET_NAME); - mBridge.start(); - - Future response = TestUtils.asyncRequest(CLIENT_SOCKET_NAME, REQUEST); - - Assert.assertEquals("", response.get()); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionControlMessagesTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionControlMessagesTest.java deleted file mode 100644 index a318168..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionControlMessagesTest.java +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.SessionControlMessages.ClientMessage; -import org.chromium.components.devtools_bridge.SessionControlMessages.ClientMessageHandler; -import org.chromium.components.devtools_bridge.SessionControlMessages.IceExchangeMessage; -import org.chromium.components.devtools_bridge.SessionControlMessages.InvalidFormatException; -import org.chromium.components.devtools_bridge.SessionControlMessages.Message; -import org.chromium.components.devtools_bridge.SessionControlMessages.MessageHandler; -import org.chromium.components.devtools_bridge.SessionControlMessages.ServerMessage; -import org.chromium.components.devtools_bridge.SessionControlMessages.ServerMessageHandler; -import org.chromium.components.devtools_bridge.SessionControlMessages.UnknownRequestMessage; -import org.chromium.components.devtools_bridge.SessionControlMessages.UnknownResponseMessage; - -/** - * Tests for {@link SessionControlMessages} - */ -public class SessionControlMessagesTest extends InstrumentationTestCase { - private static final String UNKNOWN_REQUEST_TYPE = "@unknown request@"; - private static final String UNKNOWN_REQUEST = "{\"type\": \"" + UNKNOWN_REQUEST_TYPE + "\"}"; - - @SmallTest - public void testIceExchangeMessage() { - recode(new IceExchangeMessage()); - } - - @SmallTest - public void testUnknownRequest() throws InvalidFormatException { - UnknownRequestMessage request = - (UnknownRequestMessage) ClientMessageReader.readMessage(UNKNOWN_REQUEST); - UnknownResponseMessage response = ServerMessageReader.recode(request.createResponse()); - Assert.assertEquals(UNKNOWN_REQUEST_TYPE, response.rawRequestType); - } - - private T recode(T message) { - assert message != null; - return ServerMessageReader.recode(message); - } - - @SuppressWarnings("unchecked") - private static T cast(T prototype, Object object) { - Assert.assertNotNull(object); - if (prototype.getClass() == object.getClass()) - return (T) object; - else - throw new ClassCastException(); - } - - private static void checkedRead(MessageHandler handler, Message message) { - try { - handler.readMessage(SessionControlMessages.toByteArray(message)); - } catch (InvalidFormatException e) { - Assert.fail(e.toString()); - } - } - - private static class ServerMessageReader extends ServerMessageHandler { - private ServerMessage mLastMessage; - - @Override - protected void onMessage(ServerMessage message) { - mLastMessage = message; - } - - public static T recode(T message) { - ServerMessageReader handler = new ServerMessageReader(); - checkedRead(handler, message); - return cast(message, handler.mLastMessage); - } - } - - private static class ClientMessageReader extends ClientMessageHandler { - private ClientMessage mLastMessage; - - @Override - protected void onMessage(ClientMessage message) { - mLastMessage = message; - } - - public static ClientMessage readMessage(String json) throws InvalidFormatException { - ClientMessageReader reader = new ClientMessageReader(); - reader.readMessage(json.getBytes()); - return reader.mLastMessage; - } - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryTest.java deleted file mode 100644 index 90a3a9c..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SessionDependencyFactoryTest.java +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import java.nio.ByteBuffer; - -/** - * Tests for {@link SessionDependencyFactory} - */ -public class SessionDependencyFactoryTest extends InstrumentationTestCase { - private static final int DATA_CHANNEL_ID = 0; - - private SessionDependencyFactory mInstance; - private AbstractPeerConnection mConnection; - private PeerConnectionObserverMock mObserver; - - @Override - protected void setUp() throws Exception { - super.setUp(); - mObserver = new PeerConnectionObserverMock(); - } - - @SmallTest - public void testCreateFactory() { - mInstance = newFactory(); - mInstance.dispose(); - } - - @SmallTest - public void testCreateConnection() { - mInstance = newFactory(); - RTCConfiguration config = new RTCConfiguration.Builder() - .addIceServer("http://expample.org") - .build(); - mInstance.createPeerConnection(config, mObserver).dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testCreateAndSetLocalOffer() throws Exception { - mInstance = newFactory(); - mConnection = newConnection(); - mConnection.createAndSetLocalDescription( - AbstractPeerConnection.SessionDescriptionType.OFFER); - - mObserver.localDescriptionAvailable.await(); - - Assert.assertEquals( - AbstractPeerConnection.SessionDescriptionType.OFFER, - mObserver.localDescriptionType); - mConnection.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testTerminateCallback() { - mInstance = newFactory(); - mConnection = newConnection(); - mConnection.createAndSetLocalDescription( - AbstractPeerConnection.SessionDescriptionType.OFFER); - - // Do not wait. - - mConnection.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testCreateAndSetLocalAnswerFailed() throws Exception { - mInstance = newFactory(); - mConnection = newConnection(); - // Creating answer without offer set must fail. - mConnection.createAndSetLocalDescription( - AbstractPeerConnection.SessionDescriptionType.ANSWER); - - mObserver.failureAvailable.await(); - - mConnection.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testSetRemoteOffer() throws Exception { - mInstance = newFactory(); - mConnection = newConnection(); - mConnection.createAndSetLocalDescription( - AbstractPeerConnection.SessionDescriptionType.OFFER); - mObserver.localDescriptionAvailable.await(); - String offer = mObserver.localDescription; - mConnection.dispose(); - - mConnection = newConnection(); - mConnection.setRemoteDescription( - AbstractPeerConnection.SessionDescriptionType.OFFER, offer); - mObserver.remoteDescriptionSet.await(); - - mConnection.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testNegotiation() throws Exception { - mInstance = newFactory(); - DataPipe pipe = new DataPipe(mInstance); - pipe.negotiate(); - pipe.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testConnection() throws Exception { - mInstance = newFactory(); - DataPipe pipe = new DataPipe(mInstance); - pipe.negotiate(); - pipe.awaitConnected(); - pipe.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testDataChannel() { - mInstance = newFactory(); - mConnection = newConnection(); - AbstractDataChannel channel = mConnection.createDataChannel(DATA_CHANNEL_ID); - - channel.registerObserver(new DataChannelObserverMock()); - channel.send(ByteBuffer.allocateDirect(1), AbstractDataChannel.MessageType.TEXT); - channel.send(ByteBuffer.allocateDirect(1), AbstractDataChannel.MessageType.BINARY); - channel.unregisterObserver(); - channel.close(); - - channel.dispose(); - mConnection.dispose(); - mInstance.dispose(); - } - - @SmallTest - public void testDataChannelOpens() throws Exception { - mInstance = newFactory(); - DataPipe pipe = new DataPipe(mInstance); - - pipe.registerDatatChannelObservers(); - - pipe.negotiate(); - - pipe.dataChannelObserver(0).opened.await(); - pipe.dataChannelObserver(1).opened.await(); - - pipe.unregisterDatatChannelObservers(); - - pipe.dispose(); - mInstance.dispose(); - } - - @MediumTest - public void testPumpData() throws Exception { - mInstance = newFactory(); - DataPipe pipe = new DataPipe(mInstance); - pipe.registerDatatChannelObservers(); - pipe.negotiate(); - pipe.dataChannelObserver(0).opened.await(); - - // Make sure data channel don't leave local references on stack - // of signaling thread. References causes failure like - // "Failed adding to JNI local ref table (has 512 entries)". - final int count = 1000; - - for (int i = 0; i < count; i++) { - pipe.send(0, "A"); - } - - for (int i = 0; i < count; i++) { - pipe.dataChannelObserver(1).received.take(); - } - - pipe.unregisterDatatChannelObservers(); - pipe.dispose(); - mInstance.dispose(); - } - - private SessionDependencyFactory newFactory() { - return SessionDependencyFactory.newInstance(); - } - - private AbstractPeerConnection newConnection() { - return newConnection(mObserver); - } - - private AbstractPeerConnection newConnection(PeerConnectionObserverMock observer) { - return mInstance.createPeerConnection(new RTCConfiguration(), observer); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java deleted file mode 100644 index 53aab71..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/SocketTunnelServerTest.java +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge; - -import android.net.LocalServerSocket; -import android.net.LocalSocket; -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.MediumTest; - -import junit.framework.Assert; - -import org.chromium.base.annotations.SuppressFBWarnings; - -import java.io.IOException; -import java.io.OutputStream; -import java.nio.ByteBuffer; - -/** - * Tests for {@link SocketTunnelServer} - */ -public class SocketTunnelServerTest extends InstrumentationTestCase { - private static final int CONNECTION_ID = 30; - private static final String SOCKET_NAME = "ksdjhflksjhdflk"; - - private static final int SERVER_CHANNEL = 1; - private static final int CLIENT_CHANNEL = 0; - - private SessionDependencyFactory mFactory; - private DataPipe mPipe; - private SocketTunnel mServer; - private LocalServerSocket mSocket; - private DataChannelObserverMock mObserverMock; - - @Override - public void setUp() throws Exception { - super.setUp(); - mFactory = SessionDependencyFactory.newInstance(); - mPipe = new DataPipe(mFactory); - mServer = mFactory.newSocketTunnelServer(SOCKET_NAME); - mServer.bind(mPipe.dataChannel(SERVER_CHANNEL)); - mSocket = new LocalServerSocket(SOCKET_NAME); - mObserverMock = new DataChannelObserverMock(); - mPipe.dataChannel(CLIENT_CHANNEL).registerObserver(mObserverMock); - mPipe.negotiate(); - mPipe.awaitConnected(); - } - - @Override - public void tearDown() throws Exception { - mPipe.dataChannel(CLIENT_CHANNEL).unregisterObserver(); - mServer.unbind(); - mPipe.dispose(); - mFactory.dispose(); - super.tearDown(); - } - - private void sendPacket(ByteBuffer packet) { - packet.position(0); - mPipe.send(CLIENT_CHANNEL, packet); - } - - @MediumTest - public void testConnectToSocket() throws IOException { - LocalSocket socket = connectToSocket(1); - socket.close(); - } - - private LocalSocket connectToSocket(int connectionId) throws IOException { - sendPacket(SocketTunnelBase.buildControlPacket( - connectionId, SocketTunnelBase.CLIENT_OPEN)); - return mSocket.accept(); - } - - private void sendClose(int connectionId) { - sendPacket(SocketTunnelBase.buildControlPacket( - connectionId, SocketTunnelBase.CLIENT_CLOSE)); - } - - @MediumTest - public void testReceiveOpenAcknowledgement() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - - receiveOpenAck(CONNECTION_ID); - - socket.close(); - } - - private PacketDecoder receivePacket() throws InterruptedException { - byte[] bytes = mObserverMock.received.take(); - ByteBuffer buffer = ByteBuffer.allocate(bytes.length); - buffer.put(bytes); - buffer.position(0); - return PacketDecoder.decode(buffer); - } - - private PacketDecoder receiveControlPacket(int connectionId) throws InterruptedException { - PacketDecoder decoder = receivePacket(); - Assert.assertTrue(decoder.isControlPacket()); - Assert.assertEquals(connectionId, decoder.connectionId()); - return decoder; - } - - private void receiveOpenAck(int connectionId) throws InterruptedException { - PacketDecoder decoder = receiveControlPacket(connectionId); - Assert.assertEquals(SocketTunnelBase.SERVER_OPEN_ACK, decoder.opCode()); - } - - private void receiveClose(int connectionId) throws InterruptedException { - PacketDecoder decoder = receiveControlPacket(connectionId); - Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode()); - } - - @MediumTest - public void testClosingSocket() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - - socket.close(); - - PacketDecoder decoder = receiveControlPacket(CONNECTION_ID); - - Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode()); - } - - @MediumTest - public void testReadData() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - - byte[] sample = "Sample".getBytes(); - - socket.getOutputStream().write(sample); - socket.getOutputStream().flush(); - socket.shutdownOutput(); - - ByteBuffer result = receiveData(CONNECTION_ID, sample.length); - Assert.assertEquals(ByteBuffer.wrap(sample), result); - } - - private ByteBuffer receiveData(int connectionId, int length) throws InterruptedException { - ByteBuffer result = ByteBuffer.allocate(length); - - while (true) { - PacketDecoder decoder = receivePacket(); - if (decoder.isDataPacket()) { - Assert.assertEquals(connectionId, decoder.connectionId()); - result.put(decoder.data()); - } else if (decoder.isControlPacket()) { - Assert.assertEquals(SocketTunnelBase.SERVER_CLOSE, decoder.opCode()); - Assert.assertEquals(connectionId, decoder.connectionId()); - break; - } - } - result.limit(result.position()); - result.position(0); - return result; - } - - private int sum(int[] values) { - int result = 0; - for (int v : values) - result += v; - return result; - } - - private static final int[] CHUNK_SIZES = - new int[] { 0, 1, 5, 100, 1000, SocketTunnelBase.READING_BUFFER_SIZE * 2 }; - - @MediumTest - public void testReadLongDataChunk() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - - byte[] buffer = new byte[CHUNK_SIZES[CHUNK_SIZES.length - 1]]; - ByteBuffer sentData = ByteBuffer.allocate(sum(CHUNK_SIZES)); - OutputStream stream = socket.getOutputStream(); - byte next = 0; - int prevSize = 0; - for (int size : CHUNK_SIZES) { - while (prevSize < size) - buffer[prevSize++] = next++; - - stream.write(buffer, 0, size); - sentData.put(buffer, 0, size); - } - - socket.shutdownOutput(); - - sentData.limit(sentData.position()); - sentData.position(0); - ByteBuffer readData = receiveData(CONNECTION_ID, sentData.limit()); - - Assert.assertEquals(sentData, readData); - } - - @SuppressFBWarnings("DLS_DEAD_LOCAL_STORE") - @MediumTest - public void testReuseConnectionId() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - - socket.close(); - receiveClose(CONNECTION_ID); - sendClose(CONNECTION_ID); - - // Open connection with the same ID - socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - } - - private static final byte[] SAMPLE = "Sample".getBytes(); - - @MediumTest - public void testWriteData() throws IOException, InterruptedException { - LocalSocket socket = connectToSocket(CONNECTION_ID); - receiveOpenAck(CONNECTION_ID); - - sendPacket(SocketTunnelBase.buildDataPacket(CONNECTION_ID, SAMPLE, SAMPLE.length)); - - byte[] result = new byte[SAMPLE.length]; - int read = 0; - while (read < SAMPLE.length) { - int count = socket.getInputStream().read(result, 0, SAMPLE.length - read); - Assert.assertTrue(count > 0); - read += count; - } - - Assert.assertEquals(ByteBuffer.wrap(SAMPLE), ByteBuffer.wrap(result)); - - socket.close(); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandlerTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandlerTest.java deleted file mode 100644 index cb4b95c..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/JsonResponseHandlerTest.java +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; -import android.util.JsonReader; - -import junit.framework.Assert; - -import org.apache.http.ProtocolVersion; -import org.apache.http.client.ClientProtocolException; -import org.apache.http.client.HttpResponseException; -import org.apache.http.entity.StringEntity; -import org.apache.http.message.BasicHttpResponse; - -import java.io.IOException; - -/** - * Tests for {@link JsonResponseHandler}. - */ -public class JsonResponseHandlerTest extends InstrumentationTestCase { - @SmallTest - public void testInvalidResponse() throws IOException { - try { - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) { - return ""; - } - }.handleResponse(newResponse(404, null)); - - Assert.fail(); - } catch (HttpResponseException e) { - // Expected - } - } - - @SmallTest - public void testIOException() { - try { - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - throw new IOException(); - } - }.handleResponse(newResponse(200, "")); - - Assert.fail(); - } catch (IOException e) { - // Expected - } - } - - @SmallTest - public void testStateException() throws IOException { - try { - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - reader.beginObject(); - reader.endObject(); - return ""; - } - }.handleResponse(newResponse(200, "[]")); - - Assert.fail(); - } catch (JsonResponseHandler.ResponseFormatException e) { - // Expected - } - } - - @SmallTest - public void testFormatException() throws IOException { - try { - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - reader.beginArray(); - reader.nextLong(); - reader.endArray(); - return ""; - } - }.handleResponse(newResponse(200, "[\"XXX\"]")); - - Assert.fail(); - } catch (JsonResponseHandler.ResponseFormatException e) { - // Expected - } - } - - @SmallTest - public void testNullResultException() throws IOException { - try { - new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - reader.beginArray(); - reader.endArray(); - return null; - } - }.handleResponse(newResponse(200, "[]")); - - Assert.fail(); - } catch (ClientProtocolException e) { - // Expected - } - } - - @SmallTest - public void testSuccess() throws IOException { - String result = new JsonResponseHandler() { - @Override - public String readResponse(JsonReader reader) throws IOException { - reader.beginArray(); - reader.endArray(); - return "OK"; - } - }.handleResponse(newResponse(200, "[]")); - - Assert.assertEquals("OK", result); - } - - private BasicHttpResponse newResponse(int status, String content) { - BasicHttpResponse response = new BasicHttpResponse( - new ProtocolVersion("HTTP", 1, 1), status, "reason"); - if (content != null) { - try { - response.setEntity(new StringEntity(content, "UTF-8")); - } catch (Exception e) { - throw new RuntimeException(e); - } - } - return response; - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/OAuthClientTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/OAuthClientTest.java deleted file mode 100644 index 78c7c54..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/apiary/OAuthClientTest.java +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.apiary; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.util.TestSource; - -/** - * Tests for {@link OAuthClient}. - */ -public class OAuthClientTest extends InstrumentationTestCase { - private static final String ACCESS_TOKEN = - "ya29.rgBgy64Y1MACXNmPDUpPGbwFuAec2NCCDJwaEp8DwLnV8RBk45p9RBqBfEQUYxL6OVB-oyktRqZj0w"; - private static final String REFRESH_TOKEN = - "1/cWihsJmDMujYfhzBVTwgh4ukiFyiiRWLmFwTv4EigzU"; - - @SmallTest - public void testResponse() throws Exception { - TestSource source = new TestSource(); - source.write() - .beginObject() - .name("access_token").value(ACCESS_TOKEN) - .name("token_type").value("Bearer") - .name("expires_in").value(3600) // seconds - .name("refresh_token").value(REFRESH_TOKEN) - .endObject() - .close(); - OAuthResult result = OAuthClient.readResponse(source.read(), 1111); - Assert.assertEquals(ACCESS_TOKEN, result.accessToken); - Assert.assertEquals(REFRESH_TOKEN, result.refreshToken); - Assert.assertEquals(1111 + 3600000, result.expirationTimeMs); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandReceiverTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandReceiverTest.java deleted file mode 100644 index e5226ff..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandReceiverTest.java +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.RTCConfiguration; -import org.chromium.components.devtools_bridge.SignalingReceiverMock; - -import java.util.ArrayList; -import java.util.List; - -/** - * Tests for {@link CommandReceiver} - */ -public class CommandReceiverTest extends InstrumentationTestCase { - private static final RTCConfiguration CONFIG = new RTCConfiguration.Builder() - .build(); - - private final SignalingReceiverMock mMock = new SignalingReceiverMock(); - private final CommandReceiver mReceiver = new CommandReceiver(mMock); - private final CompletionHandler mCompletionHandler = new CompletionHandler(); - - private static class CompletionHandler implements Runnable { - public boolean done = false; - - @Override - public void run() { - done = true; - } - }; - - @SmallTest - public void testStartSessionCommand() { - Commands.StartSessionCommand command = - new Commands.StartSessionCommand("SESSION_ID", CONFIG, "OFFER"); - - mReceiver.receive(command, mCompletionHandler); - Assert.assertEquals("SESSION_ID", mMock.sessionId); - Assert.assertEquals("OFFER", mMock.offer); - - mMock.negotiationCallback.onSuccess("ANSWER"); - Assert.assertTrue(mCompletionHandler.done); - Assert.assertEquals(command.getResult(), "ANSWER"); - } - - @SmallTest - public void testRenegotiateCommand() { - Commands.RenegotiateCommand command = - new Commands.RenegotiateCommand("SESSION_ID", "OFFER"); - - mReceiver.receive(command, mCompletionHandler); - Assert.assertEquals("SESSION_ID", mMock.sessionId); - Assert.assertEquals("OFFER", mMock.offer); - - mMock.negotiationCallback.onSuccess("ANSWER"); - Assert.assertTrue(mCompletionHandler.done); - Assert.assertEquals(command.getResult(), "ANSWER"); - } - - @SmallTest - public void testIceExchangeCommand() { - List candidates = new ArrayList(); - - Commands.IceExchangeCommand command = - new Commands.IceExchangeCommand("SESSION_ID", candidates); - - mReceiver.receive(command, mCompletionHandler); - Assert.assertEquals("SESSION_ID", mMock.sessionId); - - mMock.iceExchangeCallback.onSuccess(candidates); - Assert.assertTrue(mCompletionHandler.done); - } - - @SmallTest - public void testCommandFailure() { - Commands.RenegotiateCommand command = - new Commands.RenegotiateCommand("SESSION_ID", "OFFER"); - - mReceiver.receive(command, mCompletionHandler); - - mMock.negotiationCallback.onFailure("ERROR_MESSAGE"); - Assert.assertTrue(mCompletionHandler.done); - Assert.assertEquals(command.getErrorMessage(), "ERROR_MESSAGE"); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandSenderTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandSenderTest.java deleted file mode 100644 index 3d03935..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandSenderTest.java +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.base.annotations.SuppressFBWarnings; -import org.chromium.components.devtools_bridge.RTCConfiguration; -import org.chromium.components.devtools_bridge.SessionBase; - -import java.util.ArrayList; -import java.util.List; - -/** - * Tests for {@link CommandSender} - */ -@SuppressFBWarnings("URF_UNREAD_FIELD") -public class CommandSenderTest extends InstrumentationTestCase { - private static final RTCConfiguration CONFIG = new RTCConfiguration.Builder() - .addIceServer("http://example.org") - .build(); - - private Command mCommand; - private Runnable mCompletionCallback; - private String mAnswer; - private String mErrorMessage; - private List mServerCandidates; - - @SmallTest - public void testStartSessionCommand() { - new SenderMock().startSession("SESSION_ID", CONFIG, "OFFER", new NegotiationCallbackMock()); - - Commands.StartSessionCommand command = (Commands.StartSessionCommand) mCommand; - Assert.assertNotNull(command); - - Assert.assertEquals("SESSION_ID", command.sessionId); - Assert.assertEquals("OFFER", command.offer); - - command.setResult("ANSWER"); - - mCompletionCallback.run(); - Assert.assertEquals("ANSWER", mAnswer); - Assert.assertNull(mErrorMessage); - } - - @SmallTest - public void testRenegotiateCommand() { - new SenderMock().renegotiate("SESSION_ID", "OFFER", new NegotiationCallbackMock()); - Commands.RenegotiateCommand command = (Commands.RenegotiateCommand) mCommand; - Assert.assertNotNull(command); - - Assert.assertEquals("SESSION_ID", command.sessionId); - Assert.assertEquals("OFFER", command.offer); - - command.setResult("ANSWER"); - - mCompletionCallback.run(); - Assert.assertEquals("ANSWER", mAnswer); - Assert.assertNull(mErrorMessage); - } - - @SmallTest - public void testIceExchangeCommand() { - ArrayList candidates = new ArrayList(); - new SenderMock().iceExchange("SESSION_ID", candidates, new IceExchangeCallbackMock()); - Commands.IceExchangeCommand command = (Commands.IceExchangeCommand) mCommand; - Assert.assertNotNull(command); - - Assert.assertEquals("SESSION_ID", command.sessionId); - command.setResult(candidates); - - mCompletionCallback.run(); - Assert.assertNull(mErrorMessage); - } - - @SmallTest - public void testCommandFailure() { - new SenderMock().renegotiate("SESSION_ID", "OFFER", new NegotiationCallbackMock()); - - Commands.RenegotiateCommand command = (Commands.RenegotiateCommand) mCommand; - Assert.assertNotNull(command); - - command.setFailure("TEST_MESSAGE"); - - mCompletionCallback.run(); - Assert.assertNull(mAnswer); - Assert.assertEquals("TEST_MESSAGE", mErrorMessage); - } - - private class SenderMock extends CommandSender { - @Override - protected void send(Command command, Runnable completionCallback) { - mCommand = command; - mCompletionCallback = completionCallback; - } - } - - private class NegotiationCallbackMock implements SessionBase.NegotiationCallback { - @Override - public void onSuccess(String answer) { - mAnswer = answer; - } - - @Override - public void onFailure(String errorMessage) { - mErrorMessage = errorMessage; - } - } - - private class IceExchangeCallbackMock implements SessionBase.IceExchangeCallback { - @Override - public void onSuccess(List serverCandidates) { - mServerCandidates = serverCandidates; - } - - @Override - public void onFailure(String errorMessage) { - mErrorMessage = errorMessage; - } - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandsTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandsTest.java deleted file mode 100644 index 2c7e6d8..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/CommandsTest.java +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import java.util.HashMap; -import java.util.Map; - -/** - * Tests for {@link Commands} - */ -public class CommandsTest extends InstrumentationTestCase { - @SmallTest - public void testStartSessionCommand() throws Exception { - CommandDefinition def = Command.Type.START_SESSION.definition; - - Assert.assertEquals("_startSession", def.shortName()); - Assert.assertEquals("base._startSession", def.fullName()); - - Assert.assertEquals(3, getParamCount(def)); - Assert.assertEquals("_sessionId", getParam(def, 0).name()); - Assert.assertEquals("_config", getParam(def, 1).name()); - Assert.assertEquals("_offer", getParam(def, 2).name()); - - Map values = new HashMap(); - values.put("_sessionId", "SESSION_ID"); - values.put("_config", "{}"); - values.put("_offer", "OFFER"); - - Commands.StartSessionCommand command = - (Commands.StartSessionCommand) def.newCommand("ID", values); - - Assert.assertEquals(Command.Type.START_SESSION, command.type); - Assert.assertEquals("ID", command.id); - Assert.assertEquals("SESSION_ID", command.sessionId); - Assert.assertEquals("OFFER", command.offer); - - visitInParams(command, values); - } - - @SmallTest - public void testRenegotiateCommand() throws Exception { - CommandDefinition def = Command.Type.RENEGOTIATE.definition; - - Assert.assertEquals("_renegotiate", def.shortName()); - Assert.assertEquals("base._renegotiate", def.fullName()); - - Assert.assertEquals(2, getParamCount(def)); - Assert.assertEquals("_sessionId", getParam(def, 0).name()); - Assert.assertEquals("_offer", getParam(def, 1).name()); - - Map values = new HashMap(); - values.put("_sessionId", "SESSION_ID"); - values.put("_offer", "OFFER"); - - Commands.RenegotiateCommand command = - (Commands.RenegotiateCommand) def.newCommand("ID", values); - - Assert.assertEquals(Command.Type.RENEGOTIATE, command.type); - Assert.assertEquals("ID", command.id); - Assert.assertEquals("OFFER", command.offer); - - visitInParams(command, values); - } - - @SmallTest - public void testIceExchangeCommand() throws Exception { - CommandDefinition def = Command.Type.ICE_EXCHANGE.definition; - - Assert.assertEquals("_iceExchange", def.shortName()); - Assert.assertEquals("base._iceExchange", def.fullName()); - - Assert.assertEquals(2, getParamCount(def)); - Assert.assertEquals("_sessionId", getParam(def, 0).name()); - Assert.assertEquals("_clientCandidates", getParam(def, 1).name()); - - Map values = new HashMap(); - values.put("_sessionId", "SESSION_ID"); - values.put("_clientCandidates", "[\"candidate\"]"); - - Commands.IceExchangeCommand command = - (Commands.IceExchangeCommand) def.newCommand("ID", values); - - Assert.assertEquals(Command.Type.ICE_EXCHANGE, command.type); - Assert.assertEquals("ID", command.id); - - visitInParams(command, values); - } - - private void visitInParams(Command command, final Map expectedValues) { - final Map actualValues = new HashMap(); - command.visitInParams(new Command.ParamVisitor() { - @Override - public void visit(ParamDefinition param, String value) { - String name = param.name(); - Assert.assertTrue(expectedValues.containsKey(name)); - actualValues.put(name, value); - } - }); - Assert.assertEquals(expectedValues.size(), actualValues.size()); - } - - private int getParamCount(CommandDefinition def) { - int count = 0; - for (ParamDefinition param : def.inParams()) { - count++; - } - return count; - } - - private ParamDefinition getParam(CommandDefinition def, int index) { - for (ParamDefinition param : def.inParams()) { - if (index == 0) return param; - index--; - } - return null; - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/ParamDefinitionsTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/ParamDefinitionsTest.java deleted file mode 100644 index 3bf72c8..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/commands/ParamDefinitionsTest.java +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.commands; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.RTCConfiguration; - -import java.util.List; - -/** - * Tests for {@link ParamDefinitions} - */ -public class ParamDefinitionsTest extends InstrumentationTestCase { - @SmallTest - public void testStringParam() throws Exception { - ParamDefinition param = ParamDefinitions.newStringParam("NAME"); - Assert.assertEquals("_NAME", param.name()); - Assert.assertEquals("string", param.type()); - Assert.assertEquals("STRING", param.fromString("STRING")); - Assert.assertEquals("STRING", param.toString("STRING")); - } - - @SmallTest - public void testStringListParam() throws Exception { - ParamDefinition> param = ParamDefinitions.newStringListParam("NAME"); - Assert.assertEquals("_NAME", param.name()); - Assert.assertEquals("string", param.type()); - - List value = param.fromString("[\"ITEM1\",\"ITEM2\"]"); - Assert.assertEquals(2, value.size()); - Assert.assertEquals("ITEM1", value.get(0)); - Assert.assertEquals("ITEM2", value.get(1)); - - try { - param.fromString("{\"ITEM1\",\"ITEM2\"}"); - Assert.fail("Exception expected"); - } catch (CommandFormatException e) { - // Expected. - } - - List clone = param.fromString(param.toString(value)); - Assert.assertEquals(value.size(), clone.size()); - Assert.assertEquals(value.get(0), clone.get(0)); - Assert.assertEquals(value.get(1), clone.get(1)); - } - - @SmallTest - public void testConfigParam() throws Exception { - ParamDefinition param = ParamDefinitions.newConfigParam("NAME"); - Assert.assertEquals("_NAME", param.name()); - Assert.assertEquals("string", param.type()); - - RTCConfiguration value = param.fromString( - "{\"iceServers\": [{\"uri\": \"http://example.org\"}]}"); - Assert.assertNotNull(value); - Assert.assertEquals(1, value.iceServers.size()); - Assert.assertEquals("http://example.org", value.iceServers.get(0).uri); - - try { - param.fromString("["); - Assert.fail("Exception expected"); - } catch (CommandFormatException e) { - // Expected. - } - - value = new RTCConfiguration.Builder() - .addIceServer("http://example.org/1", "USERNAME", "CREDENTIAL") - .addIceServer("http://example.org/2", "USERNAME", "CREDENTIAL") - .build(); - RTCConfiguration clone = param.fromString(param.toString(value)); - Assert.assertEquals(value.iceServers.size(), clone.iceServers.size()); - Assert.assertEquals(value.iceServers.get(0).username, clone.iceServers.get(0).username); - Assert.assertEquals(value.iceServers.get(1).credential, clone.iceServers.get(1).credential); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/gcd/MessageReaderTest.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/gcd/MessageReaderTest.java deleted file mode 100644 index 72b5254..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/gcd/MessageReaderTest.java +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.gcd; - -import android.test.InstrumentationTestCase; -import android.test.suitebuilder.annotation.SmallTest; - -import junit.framework.Assert; - -import org.chromium.components.devtools_bridge.commands.Command; -import org.chromium.components.devtools_bridge.util.TestSource; - -/** - * Tests for {@link MessageReader}. - */ -public class MessageReaderTest extends InstrumentationTestCase { - private static final String DEVICE_ID = "4ac8a0f8-??????????????-192e2727710d"; - private static final String ROBOT_ACCOUNT_EMAIL = - "2a3???????????????????????????87@clouddevices.gserviceaccount.com"; - private static final String AUTHORIZATION_CODE = - "4/6V0jpup-????????????????????????????????????????????_e85kQI"; - private static final String COMMAND_ID = - "a0217abb-????-????-????-?????????????????????????-????-2725-b2332fe99829"; - - @SmallTest - public void testReadTicket() throws Exception { - TestSource source = new TestSource(); - source.write().beginObject() - .name("kind").value("clouddevices#registrationTicket") - .name("id").value("p8hI4") - .name("deviceId").value(DEVICE_ID) - .name("creationTimeMs").value("1411029429794") - .name("expirationTimeMs").value("1411029669794") - .endObject().close(); - String result = new MessageReader(source.read()).readTicketId(); - Assert.assertEquals("p8hI4", result); - } - - @SmallTest - public void testReadCredential() throws Exception { - TestSource source = new TestSource(); - source.write().beginObject() - .name("kind").value("clouddevices#registrationTicket") - .name("id").value("p8hI4") - .name("deviceId").value(DEVICE_ID) - .name("userEmail").value("...@chromium.org") - .name("creationTimeMs").value("1411029429794") - .name("expirationTimeMs").value("1411029669794") - .name("robotAccountEmail").value(ROBOT_ACCOUNT_EMAIL) - .name("robotAccountAuthorizationCode").value(AUTHORIZATION_CODE) - .endObject().close(); - InstanceCredential result = new MessageReader(source.read()).readInstanceCredential(); - Assert.assertEquals(DEVICE_ID, result.id); - Assert.assertEquals(AUTHORIZATION_CODE, result.secret); - } - - @SmallTest - public void testReadNotificationCommandCreated() throws Exception { - TestSource source = new TestSource(); - source.write().beginObject() - .name("type").value("COMMAND_CREATED") - .name("commandId").value(COMMAND_ID) - .name("deviceId").value(DEVICE_ID) - .name("command").beginObject() - .name("kind").value("clouddevices#command") - .name("id").value(COMMAND_ID) - .name("deviceId").value(DEVICE_ID) - .name("name").value("base._startSession") - .name("parameters").beginObject() - .name("_sessionId").value("SESSION_ID") - .name("_config").value("{}") - .name("_offer").value("INVALID_OFFER") - .endObject() // parameters - .name("state").value("queued") - .name("error").beginObject() - .name("arguments").beginArray().endArray() - .name("creationTimeMs").value("1411137527329") - .name("expirationTimeMs").value("1411137547329") - .endObject() // error - .endObject() // command - .name("expirationTimeMs").value("1411029669794") - .endObject().close(); - Notification result = new MessageReader(source.read()).readNotification(); - - Assert.assertEquals(Notification.Type.COMMAND_CREATED, result.type); - Assert.assertEquals(DEVICE_ID, result.instanceId); - Assert.assertNotNull(result.command); - Assert.assertEquals(COMMAND_ID, result.command.id); - Assert.assertEquals(Command.Type.START_SESSION, result.command.type); - } - - @SmallTest - public void testReadNotificationCommandExpired() throws Exception { - TestSource source = new TestSource(); - source.write().beginObject() - .name("type").value("COMMAND_EXPIRED") - .name("commandId").value(COMMAND_ID) - .name("deviceId").value(DEVICE_ID) - .endObject().close(); - Notification result = new MessageReader(source.read()).readNotification(); - Assert.assertNull(result); - } - - @SmallTest - public void testReadNotificationInstanceUNregistered() throws Exception { - TestSource source = new TestSource(); - source.write().beginObject() - .name("type").value("DEVICE_DELETED") - .name("deviceId").value(DEVICE_ID) - .endObject().close(); - Notification result = new MessageReader(source.read()).readNotification(); - - Assert.assertEquals(Notification.Type.INSTANCE_UNREGISTERED, result.type); - Assert.assertEquals(DEVICE_ID, result.instanceId); - Assert.assertNull(result.command); - } -} diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugActivity.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugActivity.java deleted file mode 100644 index 3fab9d3..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugActivity.java +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.tests; - -import android.app.Activity; -import android.content.Intent; -import android.os.Build; -import android.os.Bundle; -import android.text.Html; -import android.text.method.LinkMovementMethod; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.Button; -import android.widget.LinearLayout; -import android.widget.LinearLayout.LayoutParams; -import android.widget.TextView; - -import org.chromium.components.devtools_bridge.ui.GCDRegistrationFragment; -import org.chromium.components.devtools_bridge.ui.RemoteInstanceListFragment; - -/** - * Activity for testing devtools bridge. - */ -public class DebugActivity extends Activity { - private static final int LAYOUT_ID = 1000; - private static final String DOC_HREF = - "https://docs.google.com/a/chromium.org/document/d/" - + "188V6TWV8ivbjAPIp6aqwffWrY78xN2an5REajZHpunk/edit?usp=sharing"; - - private LinearLayout mLayout; - - @Override - public void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - - mLayout = new LinearLayout(this); - mLayout.setId(LAYOUT_ID); - mLayout.setOrientation(LinearLayout.VERTICAL); - - TextView textView = new TextView(this); - textView.setText(Html.fromHtml( - "See testing instructions.")); - textView.setMovementMethod(LinkMovementMethod.getInstance()); - mLayout.addView(textView); - - addActionButton("Start LocalSessionBridge", DebugService.START_SESSION_BRIDGE_ACTION); - addActionButton("Start DevToolsBridgeServer", DebugService.START_SERVER_ACTION); - addActionButton("Stop", DebugService.STOP_ACTION); - - LayoutParams layoutParam = new LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.MATCH_PARENT); - - getFragmentManager() - .beginTransaction() - .add(LAYOUT_ID, new TestGCDRegistrationFragment()) - .add(LAYOUT_ID, new RemoteInstanceListFragmentImpl()) - .commit(); - - setContentView(mLayout, layoutParam); - } - - private void addActionButton(String text, String action) { - Button button = new Button(this); - button.setText(text); - button.setOnClickListener(new SendActionOnClickListener(action)); - mLayout.addView(button); - } - - private class SendActionOnClickListener implements View.OnClickListener { - private final String mAction; - - SendActionOnClickListener(String action) { - mAction = action; - } - - @Override - public void onClick(View v) { - Intent intent = new Intent(DebugActivity.this, DebugService.class); - intent.setAction(mAction); - startService(intent); - } - } - - private static class TestGCDRegistrationFragment - extends GCDRegistrationFragment implements View.OnClickListener { - private Button mButton; - - @Override - public View onCreateView( - LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - mButton = new Button(getActivity()); - mButton.setOnClickListener(this); - updateText(); - return mButton; - } - - public void updateText() { - mButton.setText(isRegistered() - ? "Unregister (registered for " + getOwner() + ")" - : "Register in GCD"); - } - - @Override - protected void onRegistrationStatusChange() { - updateText(); - } - - @Override - protected String generateDisplayName() { - return Build.MODEL + " Test app"; - } - - @Override - public void onClick(View v) { - if (!isRegistered()) { - register(); - } else { - unregister(); - } - } - } - - private final class RemoteInstanceListFragmentImpl extends RemoteInstanceListFragment { - @Override - protected void connect(String oAuthToken, String remoteInstanceId) { - startService(new Intent(DebugActivity.this, DebugService.class) - .setAction(DebugService.START_GCD_CLIENT_ACTION) - .putExtra(DebugService.EXTRA_OAUTH_TOKEN, oAuthToken) - .putExtra(DebugService.EXTRA_REMOTE_INSTANCE_ID, remoteInstanceId)); - } - } -} - diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugService.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugService.java deleted file mode 100644 index b009555..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/DebugService.java +++ /dev/null @@ -1,243 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.tests; - -import android.app.Notification; -import android.app.PendingIntent; -import android.app.Service; -import android.content.Intent; -import android.os.Binder; -import android.os.IBinder; -import android.os.Process; -import android.widget.Toast; - -import org.chromium.components.devtools_bridge.DevToolsBridgeServerSandbox; -import org.chromium.components.devtools_bridge.GCDClientSessionTestingHost; -import org.chromium.components.devtools_bridge.LocalSessionBridge; - -import java.io.IOException; - -/** - * Service for testing devtools bridge. - */ -public class DebugService extends Service { - public static final String START_SESSION_BRIDGE_ACTION = "action.START_SESSION_BRIDGE"; - public static final String START_SERVER_ACTION = "action.START_SERVER"; - public static final String START_GCD_CLIENT_ACTION = "action.START_GCD_CLIENT"; - public static final String STOP_ACTION = "action.STOP"; - - public static final String EXTRA_OAUTH_TOKEN = "extra.OAUTH_TOKEN"; - public static final String EXTRA_REMOTE_INSTANCE_ID = "extra.REMOTE_INSTANCE_ID"; - - private static final int NOTIFICATION_ID = 1; - - private Controller mRunningController; - - private interface Controller { - void create() throws IOException; - void start() throws Exception; - void stop(); - void dispose(); - } - - private String replicatingSocketName() { - return "chrome_shell_devtools_remote"; - } - - private String exposingSocketName() { - return "webview_devtools_remote_" + Integer.valueOf(Process.myPid()); - } - - private class LocalSessionBridgeController implements Controller { - private LocalSessionBridge mBridge; - - @Override - public void create() throws IOException { - mBridge = new LocalSessionBridge(replicatingSocketName(), exposingSocketName()); - } - - @Override - public void start() { - mBridge.start(); - } - - @Override - public void stop() { - mBridge.stop(); - } - - @Override - public void dispose() { - mBridge.dispose(); - } - - @Override - public String toString() { - return "LocalSessionBridge"; - } - } - - private class DevToolsBridgeServerSandboxController implements Controller { - private DevToolsBridgeServerSandbox mSandbox; - - @Override - public void create() { - mSandbox = new DevToolsBridgeServerSandbox(); - } - - @Override - public void start() throws Exception { - mSandbox.start(DebugService.this); - } - - @Override - public void stop() { - mSandbox.stop(); - } - - @Override - public void dispose() {} - - @Override - public String toString() { - return "DevToolsBridgeServerSandbox"; - } - } - - private class GCDClientController implements Controller { - private final String mOAuthToken; - private final String mRemoteInstanceId; - - private GCDClientSessionTestingHost mHost; - - public GCDClientController(String oAuthToken, String remoteInstanceId) { - mOAuthToken = oAuthToken; - mRemoteInstanceId = remoteInstanceId; - } - - @Override - public void create() { - } - - @Override - public void start() throws Exception { - final GCDClientSessionTestingHost host = new GCDClientSessionTestingHost( - mOAuthToken, exposingSocketName(), mRemoteInstanceId); - host.start(new Runnable() { - @Override - public void run() { - String text; - if (!host.isStarted()) { - text = "Session not started. See log for details"; - } else { - text = "Session started"; - } - Toast.makeText(DebugService.this, text, Toast.LENGTH_SHORT).show(); - } - }); - mHost = host; - } - - @Override - public void stop() { - } - - @Override - public void dispose() { - mHost.dispose(); - } - - @Override - public String toString() { - return "GCDClientSessionTestingHost"; - } - } - - @Override - public int onStartCommand(Intent intent, int flags, int startId) { - if (intent == null) return START_NOT_STICKY; - - String action = intent.getAction(); - if (START_SESSION_BRIDGE_ACTION.equals(action)) { - return start(new LocalSessionBridgeController()); - } else if (START_SERVER_ACTION.equals(action)) { - return start(new DevToolsBridgeServerSandboxController()); - } else if (START_GCD_CLIENT_ACTION.equals(action)) { - String oAuthToken = intent.getStringExtra(EXTRA_OAUTH_TOKEN); - String remoteInstanceId = intent.getStringExtra(EXTRA_REMOTE_INSTANCE_ID); - return start(new GCDClientController(oAuthToken, remoteInstanceId)); - } else if (STOP_ACTION.equals(action)) { - return stop(); - } - return START_NOT_STICKY; - } - - private int start(Controller controller) { - if (mRunningController != null) { - Toast.makeText(this, "Already started", Toast.LENGTH_SHORT).show(); - return START_NOT_STICKY; - } - - try { - controller.create(); - controller.start(); - } catch (Exception e) { - e.printStackTrace(); - Toast.makeText(this, "Failed to start", Toast.LENGTH_SHORT).show(); - controller.dispose(); - return START_NOT_STICKY; - } - mRunningController = controller; - - startForeground(NOTIFICATION_ID, makeForegroundServiceNotification()); - Toast.makeText(this, controller.toString() + " started", Toast.LENGTH_SHORT).show(); - return START_STICKY; - } - - private int stop() { - if (mRunningController == null) - return START_NOT_STICKY; - - String name = mRunningController.toString(); - mRunningController.stop(); - mRunningController.dispose(); - mRunningController = null; - stopSelf(); - Toast.makeText(this, name + " stopped", Toast.LENGTH_SHORT).show(); - return START_NOT_STICKY; - } - - @Override - public IBinder onBind(Intent intent) { - return new Binder(); - } - - private Notification makeForegroundServiceNotification() { - Intent showInfoIntent = new Intent(this, DebugActivity.class); - showInfoIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); - PendingIntent showInfoPendingIntent = - PendingIntent.getActivity(DebugService.this, 0, showInfoIntent, 0); - - Intent stopIntent = new Intent(this, DebugService.class); - stopIntent.setAction(STOP_ACTION); - PendingIntent stopPendingIntent = - PendingIntent.getService(DebugService.this, 0, stopIntent, 0); - - return new Notification.Builder(this) - // Mandatory fiends - .setSmallIcon(android.R.drawable.alert_dark_frame) - .setContentTitle("DevTools Bridge") - .setContentText("DevTools socket local test tunnel works") - - // Optional - .setContentIntent(showInfoPendingIntent) - .addAction(android.R.drawable.ic_delete, - "Stop", stopPendingIntent) - .setOngoing(true) - .setWhen(System.currentTimeMillis()) - .build(); - } -} - diff --git a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/TestApplication.java b/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/TestApplication.java deleted file mode 100644 index d6b16ba..0000000 --- a/components/devtools_bridge/android/javatests/src/org/chromium/components/devtools_bridge/tests/TestApplication.java +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2014 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.components.devtools_bridge.tests; - -import android.app.Application; - -import org.chromium.base.library_loader.LibraryLoader; -import org.chromium.base.library_loader.LibraryProcessType; -import org.chromium.base.library_loader.ProcessInitException; -import org.chromium.components.devtools_bridge.SessionDependencyFactory; -import org.chromium.components.devtools_bridge.SessionDependencyFactoryNative; - -/** - * Performs initialization for DevTools Bridge test APK. - */ -public class TestApplication extends Application { - static { - System.loadLibrary("devtools_bridge_natives_so"); - SessionDependencyFactory.init(SessionDependencyFactoryNative.class); - try { - LibraryLoader.get(LibraryProcessType.PROCESS_BROWSER).ensureInitialized(); - } catch (ProcessInitException e) { - throw new RuntimeException(e); - } - } -} diff --git a/components/devtools_bridge/android/session_dependency_factory_android.cc b/components/devtools_bridge/android/session_dependency_factory_android.cc deleted file mode 100644 index 50c81c5..0000000 --- a/components/devtools_bridge/android/session_dependency_factory_android.cc +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright 2014 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. - -#include "components/devtools_bridge/android/session_dependency_factory_android.h" - -#include "base/android/jni_string.h" -#include "base/android/scoped_java_ref.h" -#include "base/bind.h" -#include "components/devtools_bridge/abstract_data_channel.h" -#include "components/devtools_bridge/abstract_peer_connection.h" -#include "components/devtools_bridge/rtc_configuration.h" -#include "components/devtools_bridge/socket_tunnel_server.h" -#include "jni/SessionDependencyFactoryNative_jni.h" - -using base::android::AttachCurrentThread; -using base::android::ConvertJavaStringToUTF8; -using base::android::ConvertUTF8ToJavaString; - -namespace devtools_bridge { -namespace android { - -namespace { - -/** - * Wraps Java observer and adapts it to native delegate. Chromium code normally - * leaves local java references for automatic disposing. It doesn't happen here - * (because calls originated from native thread). For instance, instead of - * - * ConvertUTF8ToJavaString(env, ...).Release() - * - * please use ConvertUTF8ToJavaString(env, ...).obj() or ScopedJavaLocalFrame. - */ -class PeerConnectionDelegateImpl - : public AbstractPeerConnection::Delegate { - public: - PeerConnectionDelegateImpl(JNIEnv* env, jobject java_object) { - java_object_.Reset(env, java_object); - connected_ = false; - } - - void OnIceConnectionChange(bool connected) override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyIceConnectionChange( - env, java_object_.obj(), connected); - } - - void OnIceCandidate(const std::string& sdp_mid, - int sdp_mline_index, - const std::string& sdp) override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyIceCandidate( - env, java_object_.obj(), - ConvertUTF8ToJavaString(env, sdp_mid).obj(), - sdp_mline_index, ConvertUTF8ToJavaString(env, sdp).obj()); - } - - void NotifyLocalOfferCreatedAndSetSet(const std::string& description) { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet( - env, java_object_.obj(), - ConvertUTF8ToJavaString(env, description).obj()); - } - - void OnLocalOfferCreatedAndSetSet(const std::string& description) override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyLocalOfferCreatedAndSetSet( - env, java_object_.obj(), - ConvertUTF8ToJavaString(env, description).obj()); - } - - void OnLocalAnswerCreatedAndSetSet(const std::string& description) override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyLocalAnswerCreatedAndSetSet( - env, java_object_.obj(), - ConvertUTF8ToJavaString(env, description).obj()); - } - - void OnRemoteDescriptionSet() override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyRemoteDescriptionSet( - env, java_object_.obj()); - } - - void OnFailure(const std::string& description) override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyConnectionFailure( - env, java_object_.obj(), - ConvertUTF8ToJavaString(env, description).obj()); - } - - private: - base::android::ScopedJavaGlobalRef java_object_; - bool connected_; -}; - -class DataChannelObserverImpl : public AbstractDataChannel::Observer { - public: - DataChannelObserverImpl(JNIEnv* env, jobject java_object) { - java_object_.Reset(env, java_object); - } - - void OnOpen() override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyChannelOpen( - env, java_object_.obj()); - } - - void OnClose() override { - JNIEnv* env = AttachCurrentThread(); - Java_SessionDependencyFactoryNative_notifyChannelClose( - env, java_object_.obj()); - } - - void OnMessage(const void* data, size_t length) override { - JNIEnv* env = AttachCurrentThread(); - - ScopedJavaLocalRef byte_buffer( - env, env->NewDirectByteBuffer(const_cast(data), length)); - - Java_SessionDependencyFactoryNative_notifyMessage( - env, java_object_.obj(), byte_buffer.obj()); - } - - private: - base::android::ScopedJavaGlobalRef java_object_; -}; - -static void CleanupOnSignalingThread() { - // Called on signaling thread when SessionDependencyFactory is destroying. - base::android::DetachFromVM(); -} - -} // namespace - -// SessionDependencyFactoryNative - -SessionDependencyFactoryAndroid::SessionDependencyFactoryAndroid() - : impl_(SessionDependencyFactory::CreateInstance( - base::Bind(&CleanupOnSignalingThread))) { -} - -SessionDependencyFactoryAndroid::~SessionDependencyFactoryAndroid() { -} - -// static -bool SessionDependencyFactoryAndroid::RegisterNatives(JNIEnv* env) { - return RegisterNativesImpl(env); -} - -scoped_ptr -SessionDependencyFactoryAndroid::CreatePeerConnection( - scoped_ptr config, - scoped_ptr delegate) { - return impl_->CreatePeerConnection(config.Pass(), delegate.Pass()); -} - -scoped_refptr -SessionDependencyFactoryAndroid::signaling_thread_task_runner() { - return impl_->signaling_thread_task_runner(); -} - -scoped_refptr -SessionDependencyFactoryAndroid::io_thread_task_runner() { - return impl_->io_thread_task_runner(); -} - -// JNI generated methods - -static jlong CreateFactory(JNIEnv* env, jclass jcaller) { - return reinterpret_cast(new SessionDependencyFactoryAndroid()); -} - -static void DestroyFactory(JNIEnv* env, jclass jcaller, jlong factory_ptr) { - delete reinterpret_cast(factory_ptr); -} - -static jlong CreateConfig(JNIEnv* env, jclass jcaller) { - return reinterpret_cast( - RTCConfiguration::CreateInstance().release()); -} - -static void AddIceServer( - JNIEnv* env, jclass jcaller, jlong config_ptr, - jstring uri, jstring username, jstring credential) { - reinterpret_cast(config_ptr)->AddIceServer( - ConvertJavaStringToUTF8(env, uri), - ConvertJavaStringToUTF8(env, username), - ConvertJavaStringToUTF8(env, credential)); -} - -static jlong CreatePeerConnection( - JNIEnv* env, jclass jcaller, - jlong factory_ptr, jlong config_ptr, jobject observer) { - auto factory = - reinterpret_cast(factory_ptr); - auto config = reinterpret_cast(config_ptr); - - auto delegate = new PeerConnectionDelegateImpl(env, observer); - - return reinterpret_cast(factory->CreatePeerConnection( - make_scoped_ptr(config), make_scoped_ptr(delegate)).release()); -} - -static void DestroyPeerConnection( - JNIEnv* env, jclass jcaller, jlong connection_ptr) { - delete reinterpret_cast(connection_ptr); -} - -static void CreateAndSetLocalOffer( - JNIEnv* env, jclass jcaller, jlong connection_ptr) { - reinterpret_cast( - connection_ptr)->CreateAndSetLocalOffer(); -} - -static void CreateAndSetLocalAnswer( - JNIEnv* env, jclass jcaller, jlong connection_ptr) { - reinterpret_cast( - connection_ptr)->CreateAndSetLocalAnswer(); -} - -static void SetRemoteOffer( - JNIEnv* env, jclass jcaller, jlong connection_ptr, jstring description) { - reinterpret_cast(connection_ptr)->SetRemoteOffer( - ConvertJavaStringToUTF8(env, description)); -} - -static void SetRemoteAnswer( - JNIEnv* env, jclass jcaller, jlong connection_ptr, jstring description) { - reinterpret_cast(connection_ptr)->SetRemoteAnswer( - ConvertJavaStringToUTF8(env, description)); -} - -static void AddIceCandidate( - JNIEnv* env, jclass jcaller, - jlong connection_ptr, jstring sdp_mid, jint sdp_mline_index, jstring sdp) { - reinterpret_cast(connection_ptr)->AddIceCandidate( - ConvertJavaStringToUTF8(env, sdp_mid), - sdp_mline_index, - ConvertJavaStringToUTF8(env, sdp)); -} - -static jlong CreateDataChannel( - JNIEnv* env, jclass jcaller, jlong connection_ptr, jint channel_id) { - return reinterpret_cast( - reinterpret_cast( - connection_ptr)->CreateDataChannel(channel_id).release()); -} - -static void DestroyDataChannel( - JNIEnv* env, jclass jcaller, jlong channel_ptr) { - delete reinterpret_cast(channel_ptr); -} - -static void RegisterDataChannelObserver( - JNIEnv* env, jclass jcaller, jlong channel_ptr, jobject observer) { - reinterpret_cast(channel_ptr)->RegisterObserver( - make_scoped_ptr(new DataChannelObserverImpl(env, observer))); -} - -static void UnregisterDataChannelObserver( - JNIEnv* env, jclass jcaller, jlong channel_ptr) { - reinterpret_cast(channel_ptr)->UnregisterObserver(); -} - -static void SendBinaryMessage( - JNIEnv* env, jclass jcaller, jlong channel_ptr, jobject message, - jint size) { - DCHECK(size > 0); - reinterpret_cast(channel_ptr)->SendBinaryMessage( - env->GetDirectBufferAddress(message), size); -} - -static void SendTextMessage( - JNIEnv* env, jclass jcaller, jlong channel_ptr, jobject message, - jint size) { - DCHECK(size > 0); - reinterpret_cast(channel_ptr)->SendTextMessage( - env->GetDirectBufferAddress(message), size); -} - -static void CloseDataChannel(JNIEnv* env, jclass jcaller, jlong channel_ptr) { - reinterpret_cast(channel_ptr)->Close(); -} - -static jlong CreateSocketTunnelServer( - JNIEnv* env, jclass jcaller, jlong factory_ptr, jlong channel_ptr, - jstring socket_name) { - return reinterpret_cast( - new SocketTunnelServer( - reinterpret_cast(factory_ptr), - reinterpret_cast(channel_ptr), - ConvertJavaStringToUTF8(env, socket_name))); -} - -static void DestroySocketTunnelServer( - JNIEnv* env, jclass jcaller, jlong tunnel_ptr) { - delete reinterpret_cast(tunnel_ptr); -} - -} // namespace android -} // namespace devtools_bridge diff --git a/components/devtools_bridge/android/session_dependency_factory_android.h b/components/devtools_bridge/android/session_dependency_factory_android.h deleted file mode 100644 index 24496de..0000000 --- a/components/devtools_bridge/android/session_dependency_factory_android.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2014 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. - -#ifndef COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_SESSION_DEPENDENCY_FACTORY_ANDROID_H_ -#define COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_SESSION_DEPENDENCY_FACTORY_ANDROID_H_ - -#include "components/devtools_bridge/session_dependency_factory.h" -#include "jni.h" - -namespace devtools_bridge { -namespace android { - -class SessionDependencyFactoryAndroid : public SessionDependencyFactory { - public: - SessionDependencyFactoryAndroid(); - ~SessionDependencyFactoryAndroid() override; - - static bool RegisterNatives(JNIEnv* env); - - scoped_ptr CreatePeerConnection( - scoped_ptr config, - scoped_ptr delegate) override; - - scoped_refptr signaling_thread_task_runner() override; - scoped_refptr io_thread_task_runner() override; - - private: - const scoped_ptr impl_; - - DISALLOW_COPY_AND_ASSIGN(SessionDependencyFactoryAndroid); -}; - -} // namespace android -} // namespace devtools_bridge - -#endif // COMPONENTS_DEVTOOLS_BRIDGE_ANDROID_SESSION_DEPENDENCY_FACTORY_ANDROID_H_ -- cgit v1.1