Remove LooperExecutor and replace it with built-in HandlerThread.

Review-Url: https://codereview.webrtc.org/2206473003
Cr-Commit-Position: refs/heads/master@{#13688}
This commit is contained in:
sakal
2016-08-09 02:03:37 -07:00
committed by Commit bot
parent 35c480cf18
commit 5d4d59c069
6 changed files with 29 additions and 292 deletions

View File

@ -13,7 +13,6 @@ package org.appspot.apprtc;
import org.appspot.apprtc.AppRTCClient.RoomConnectionParameters;
import org.appspot.apprtc.AppRTCClient.SignalingParameters;
import org.appspot.apprtc.PeerConnectionClient.PeerConnectionParameters;
import org.appspot.apprtc.util.LooperExecutor;
import android.app.Activity;
import android.app.AlertDialog;
@ -263,7 +262,7 @@ public class CallActivity extends Activity
// Create connection client. Use DirectRTCClient if room name is an IP otherwise use the
// standard WebSocketRTCClient.
if (loopback || !DirectRTCClient.IP_PATTERN.matcher(roomId).matches()) {
appRtcClient = new WebSocketRTCClient(this, new LooperExecutor());
appRtcClient = new WebSocketRTCClient(this);
} else {
Log.i(TAG, "Using DirectRTCClient because room name looks like an IP.");
appRtcClient = new DirectRTCClient(this);

View File

@ -12,8 +12,8 @@ package org.appspot.apprtc;
import org.appspot.apprtc.util.AsyncHttpURLConnection;
import org.appspot.apprtc.util.AsyncHttpURLConnection.AsyncHttpEvents;
import org.appspot.apprtc.util.LooperExecutor;
import android.os.Handler;
import android.util.Log;
import de.tavendo.autobahn.WebSocket.WebSocketConnectionObserver;
@ -39,7 +39,7 @@ public class WebSocketChannelClient {
private static final String TAG = "WSChannelRTCClient";
private static final int CLOSE_TIMEOUT = 1000;
private final WebSocketChannelEvents events;
private final LooperExecutor executor;
private final Handler handler;
private WebSocketConnection ws;
private WebSocketObserver wsObserver;
private String wsServerUrl;
@ -70,8 +70,8 @@ public class WebSocketChannelClient {
void onWebSocketError(final String description);
}
public WebSocketChannelClient(LooperExecutor executor, WebSocketChannelEvents events) {
this.executor = executor;
public WebSocketChannelClient(Handler handler, WebSocketChannelEvents events) {
this.handler = handler;
this.events = events;
roomID = null;
clientID = null;
@ -204,7 +204,7 @@ public class WebSocketChannelClient {
private void reportError(final String errorMessage) {
Log.e(TAG, errorMessage);
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (state != WebSocketConnectionState.ERROR) {
@ -233,10 +233,10 @@ public class WebSocketChannelClient {
httpConnection.send();
}
// Helper method for debugging purposes. Ensures that WebSocket method is
// called on a looper thread.
// Helper method for debugging purposes. Ensures that WebSocket method is
// called on a looper thread.
private void checkIfCalledOnValidThread() {
if (!executor.checkOnLooperThread()) {
if (Thread.currentThread() != handler.getLooper().getThread()) {
throw new IllegalStateException(
"WebSocket method is not called on valid thread");
}
@ -246,7 +246,7 @@ public class WebSocketChannelClient {
@Override
public void onOpen() {
Log.d(TAG, "WebSocket connection opened to: " + wsServerUrl);
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
state = WebSocketConnectionState.CONNECTED;
@ -266,7 +266,7 @@ public class WebSocketChannelClient {
closeEvent = true;
closeEventLock.notify();
}
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (state != WebSocketConnectionState.CLOSED) {
@ -281,7 +281,7 @@ public class WebSocketChannelClient {
public void onTextMessage(String payload) {
Log.d(TAG, "WSS->C: " + payload);
final String message = payload;
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (state == WebSocketConnectionState.CONNECTED

View File

@ -15,8 +15,9 @@ import org.appspot.apprtc.WebSocketChannelClient.WebSocketChannelEvents;
import org.appspot.apprtc.WebSocketChannelClient.WebSocketConnectionState;
import org.appspot.apprtc.util.AsyncHttpURLConnection;
import org.appspot.apprtc.util.AsyncHttpURLConnection.AsyncHttpEvents;
import org.appspot.apprtc.util.LooperExecutor;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Log;
import org.json.JSONArray;
@ -48,7 +49,7 @@ public class WebSocketRTCClient implements AppRTCClient,
private enum MessageType {
MESSAGE, LEAVE
};
private final LooperExecutor executor;
private final Handler handler;
private boolean initiator;
private SignalingEvents events;
private WebSocketChannelClient wsClient;
@ -57,11 +58,12 @@ public class WebSocketRTCClient implements AppRTCClient,
private String messageUrl;
private String leaveUrl;
public WebSocketRTCClient(SignalingEvents events, LooperExecutor executor) {
public WebSocketRTCClient(SignalingEvents events) {
this.events = events;
this.executor = executor;
roomState = ConnectionState.NEW;
executor.requestStart();
final HandlerThread handlerThread = new HandlerThread(TAG);
handlerThread.start();
handler = new Handler(handlerThread.getLooper());
}
// --------------------------------------------------------------------
@ -71,7 +73,7 @@ public class WebSocketRTCClient implements AppRTCClient,
@Override
public void connectToRoom(RoomConnectionParameters connectionParameters) {
this.connectionParameters = connectionParameters;
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
connectToRoomInternal();
@ -81,13 +83,13 @@ public class WebSocketRTCClient implements AppRTCClient,
@Override
public void disconnectFromRoom() {
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
disconnectFromRoomInternal();
handler.getLooper().quit();
}
});
executor.requestStop();
}
// Connects to room - function runs on a local looper thread.
@ -95,13 +97,13 @@ public class WebSocketRTCClient implements AppRTCClient,
String connectionUrl = getConnectionUrl(connectionParameters);
Log.d(TAG, "Connect to room: " + connectionUrl);
roomState = ConnectionState.NEW;
wsClient = new WebSocketChannelClient(executor, this);
wsClient = new WebSocketChannelClient(handler, this);
RoomParametersFetcherEvents callbacks = new RoomParametersFetcherEvents() {
@Override
public void onSignalingParametersReady(
final SignalingParameters params) {
WebSocketRTCClient.this.executor.execute(new Runnable() {
WebSocketRTCClient.this.handler.post(new Runnable() {
@Override
public void run() {
WebSocketRTCClient.this.signalingParametersReady(params);
@ -184,7 +186,7 @@ public class WebSocketRTCClient implements AppRTCClient,
// Send local offer SDP to the other participant.
@Override
public void sendOfferSdp(final SessionDescription sdp) {
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (roomState != ConnectionState.CONNECTED) {
@ -209,7 +211,7 @@ public class WebSocketRTCClient implements AppRTCClient,
// Send local answer SDP to the other participant.
@Override
public void sendAnswerSdp(final SessionDescription sdp) {
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (connectionParameters.loopback) {
@ -227,7 +229,7 @@ public class WebSocketRTCClient implements AppRTCClient,
// Send Ice candidate to the other participant.
@Override
public void sendLocalIceCandidate(final IceCandidate candidate) {
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
JSONObject json = new JSONObject();
@ -256,7 +258,7 @@ public class WebSocketRTCClient implements AppRTCClient,
// Send removed Ice candidates to the other participant.
@Override
public void sendLocalIceCandidateRemovals(final IceCandidate[] candidates) {
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
JSONObject json = new JSONObject();
@ -359,7 +361,7 @@ public class WebSocketRTCClient implements AppRTCClient,
// Helper functions.
private void reportError(final String errorMessage) {
Log.e(TAG, errorMessage);
executor.execute(new Runnable() {
handler.post(new Runnable() {
@Override
public void run() {
if (roomState != ConnectionState.ERROR) {

View File

@ -1,140 +0,0 @@
/*
* Copyright 2015 The WebRTC Project Authors. All rights reserved.
*
* Use of this source code is governed by a BSD-style license
* that can be found in the LICENSE file in the root of the source
* tree. An additional intellectual property rights grant can be found
* in the file PATENTS. All contributing project authors may
* be found in the AUTHORS file in the root of the source tree.
*/
package org.appspot.apprtc.util;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Executor;
/**
* Looper based executor class. This is needed because WebSocketClient from autobanh requires the
* thread to have a looper. The class is used in WebSocketRTCClient/WebSocketChannelClient.
*/
public class LooperExecutor extends Thread implements Executor {
private static final String TAG = "LooperExecutor";
// Object used to signal that looper thread has started and Handler instance
// associated with looper thread has been allocated.
private final Object looperStartedEvent = new Object();
private final List<Runnable> scheduledPeriodicRunnables = new LinkedList<Runnable>();
private Handler handler = null;
private boolean running = false;
private long threadId;
@Override
public void run() {
Looper.prepare();
synchronized (looperStartedEvent) {
Log.d(TAG, "Looper thread started.");
handler = new Handler();
threadId = Thread.currentThread().getId();
looperStartedEvent.notify();
}
Looper.loop();
}
public synchronized void requestStart() {
if (running) {
return;
}
running = true;
handler = null;
start();
// Wait for Hander allocation.
synchronized (looperStartedEvent) {
while (handler == null) {
try {
looperStartedEvent.wait();
} catch (InterruptedException e) {
Log.e(TAG, "Can not start looper thread");
running = false;
}
}
}
}
public synchronized void requestStop() {
if (!running) {
return;
}
running = false;
handler.post(new Runnable() {
@Override
public void run() {
handler.getLooper().quit();
Log.d(TAG, "Looper thread finished.");
}
});
}
// Checks if current thread is a looper thread.
public boolean checkOnLooperThread() {
return (Thread.currentThread().getId() == threadId);
}
public synchronized void scheduleAtFixedRate(final Runnable command, final long periodMillis) {
if (!running) {
Log.w(TAG, "Trying to schedule task for non running executor");
return;
}
Runnable runnable = new Runnable() {
@Override
public void run() {
if (running) {
command.run();
if (!handler.postDelayed(this, periodMillis)) {
Log.e(TAG, "Failed to post a delayed runnable in the chain.");
}
}
}
};
scheduledPeriodicRunnables.add(runnable);
if (!handler.postDelayed(runnable, periodMillis)) {
Log.e(TAG, "Failed to post a delayed runnable.");
}
}
public synchronized void cancelScheduledTasks() {
if (!running) {
Log.w(TAG, "Trying to cancel schedule tasks for non running executor");
return;
}
// Stop scheduled periodic tasks.
for (Runnable r : scheduledPeriodicRunnables) {
handler.removeCallbacks(r);
}
scheduledPeriodicRunnables.clear();
}
@Override
public synchronized void execute(final Runnable runnable) {
if (!running) {
Log.w(TAG, "Running looper executor without calling requestStart()");
return;
}
if (Thread.currentThread().getId() == threadId) {
runnable.run();
} else {
handler.post(runnable);
}
}
/**
* Access to the handler for testing purposes.
*/
Handler getHandler() {
return handler;
}
}