Remove peer connection and signaling calls from UI thread.
- Add separate looper threads for peer connection and websocket signaling classes. - To improve the connection speed start peer connection factory initialization once EGL context is ready in parallel with the room connection. - Add asynchronious http request class and start using it in webscoket signaling and room parameters extractor. - Add helper looper based executor class. - Port some of henrika changes from https://webrtc-codereview.appspot.com/36629004/ to fix sensor crashes on non L devices - will remove the change if CL will be submitted soon. R=jiayl@webrtc.org, wzh@webrtc.org Review URL: https://webrtc-codereview.appspot.com/41369004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@8006 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
		| @@ -27,6 +27,8 @@ | ||||
|  | ||||
| package org.appspot.apprtc; | ||||
|  | ||||
| import org.appspot.apprtc.AppRTCClient.SignalingParameters; | ||||
|  | ||||
| import android.app.Activity; | ||||
| import android.app.AlertDialog; | ||||
| import android.app.Fragment; | ||||
| @@ -49,9 +51,7 @@ import android.widget.ImageButton; | ||||
| import android.widget.TextView; | ||||
| import android.widget.Toast; | ||||
|  | ||||
| import org.appspot.apprtc.AppRTCClient.SignalingParameters; | ||||
| import org.webrtc.IceCandidate; | ||||
| import org.webrtc.PeerConnectionFactory; | ||||
| import org.webrtc.SessionDescription; | ||||
| import org.webrtc.StatsObserver; | ||||
| import org.webrtc.StatsReport; | ||||
| @@ -71,7 +71,7 @@ public class AppRTCDemoActivity extends Activity | ||||
|     implements AppRTCClient.SignalingEvents, | ||||
|       PeerConnectionClient.PeerConnectionEvents { | ||||
|   private static final String TAG = "AppRTCClient"; | ||||
|   private PeerConnectionClient pc; | ||||
|   private PeerConnectionClient pc = null; | ||||
|   private AppRTCClient appRtcClient; | ||||
|   private SignalingParameters signalingParameters; | ||||
|   private AppRTCAudioManager audioManager = null; | ||||
| @@ -123,7 +123,12 @@ public class AppRTCDemoActivity extends Activity | ||||
|     roomNameView = (TextView) findViewById(R.id.room_name); | ||||
|     videoView = (GLSurfaceView) findViewById(R.id.glview); | ||||
|  | ||||
|     VideoRendererGui.setView(videoView); | ||||
|     VideoRendererGui.setView(videoView, new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         createPeerConnectionFactory(); | ||||
|       } | ||||
|     }); | ||||
|     scalingType = ScalingType.SCALE_ASPECT_FILL; | ||||
|     remoteRender = VideoRendererGui.create(0, 0, 100, 100, scalingType, false); | ||||
|     localRender = VideoRendererGui.create(0, 0, 100, 100, scalingType, true); | ||||
| @@ -201,17 +206,6 @@ public class AppRTCDemoActivity extends Activity | ||||
|     hudView.setVisibility(View.INVISIBLE); | ||||
|     addContentView(hudView, hudLayout); | ||||
|  | ||||
|     // Create and audio manager that will take care of audio routing, | ||||
|     // audio modes, audio device enumeration etc. | ||||
|     audioManager = AppRTCAudioManager.create(this, new Runnable() { | ||||
|         // This method will be called each time the audio state (number and | ||||
|         // type of devices) has been changed. | ||||
|         public void run() { | ||||
|           onAudioManagerChangedState(); | ||||
|         } | ||||
|       } | ||||
|     ); | ||||
|  | ||||
|     final Intent intent = getIntent(); | ||||
|     Uri url = intent.getData(); | ||||
|     roomName = intent.getStringExtra(ConnectActivity.EXTRA_ROOMNAME); | ||||
| @@ -225,6 +219,7 @@ public class AppRTCDemoActivity extends Activity | ||||
|  | ||||
|     if (url != null) { | ||||
|       if (loopback || (roomName != null && !roomName.equals(""))) { | ||||
|         // Start room connection. | ||||
|         logAndToast(getString(R.string.connecting_to, url)); | ||||
|         appRtcClient = new WebSocketRTCClient(this); | ||||
|         appRtcClient.connectToRoom(url.toString(), loopback); | ||||
| @@ -233,6 +228,23 @@ public class AppRTCDemoActivity extends Activity | ||||
|         } else { | ||||
|           roomNameView.setText(roomName); | ||||
|         } | ||||
|  | ||||
|         // Create and audio manager that will take care of audio routing, | ||||
|         // audio modes, audio device enumeration etc. | ||||
|         audioManager = AppRTCAudioManager.create(this, new Runnable() { | ||||
|             // This method will be called each time the audio state (number and | ||||
|             // type of devices) has been changed. | ||||
|             @Override | ||||
|             public void run() { | ||||
|               onAudioManagerChangedState(); | ||||
|             } | ||||
|           } | ||||
|         ); | ||||
|         // Store existing audio settings and change audio mode to | ||||
|         // MODE_IN_COMMUNICATION for best possible VoIP performance. | ||||
|         Log.d(TAG, "Initializing the audio manager..."); | ||||
|         audioManager.init(); | ||||
|  | ||||
|         // For command line execution run connection for <runTimeMs> and exit. | ||||
|         if (commandLineRun && runTimeMs > 0) { | ||||
|           videoView.postDelayed(new Runnable() { | ||||
| @@ -254,6 +266,21 @@ public class AppRTCDemoActivity extends Activity | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Create peer connection factory when EGL context is ready. | ||||
|   private void createPeerConnectionFactory() { | ||||
|     final AppRTCDemoActivity thisCopy = this; | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (pc == null) { | ||||
|           pc = new PeerConnectionClient(); | ||||
|           pc.createPeerConnectionFactory( | ||||
|               thisCopy, hwCodec, VideoRendererGui.getEGLContext(), thisCopy); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * MenuBar fragment for AppRTC. | ||||
|    */ | ||||
| @@ -291,6 +318,9 @@ public class AppRTCDemoActivity extends Activity | ||||
|   protected void onDestroy() { | ||||
|     disconnect(); | ||||
|     super.onDestroy(); | ||||
|     if (logToast != null) { | ||||
|       logToast.cancel(); | ||||
|     } | ||||
|     activityRunning = false; | ||||
|   } | ||||
|  | ||||
| @@ -312,7 +342,7 @@ public class AppRTCDemoActivity extends Activity | ||||
|   // Disconnect from remote resources, dispose of local resources, and exit. | ||||
|   private void disconnect() { | ||||
|     if (appRtcClient != null) { | ||||
|       appRtcClient.disconnect(); | ||||
|       appRtcClient.disconnectFromRoom(); | ||||
|       appRtcClient = null; | ||||
|     } | ||||
|     if (pc != null) { | ||||
| @@ -349,13 +379,6 @@ public class AppRTCDemoActivity extends Activity | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Poor-man's assert(): die with |msg| unless |condition| is true. | ||||
|   private static void abortUnless(boolean condition, String msg) { | ||||
|     if (!condition) { | ||||
|       throw new RuntimeException(msg); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   // Log |msg| and Toast about it. | ||||
|   private void logAndToast(String msg) { | ||||
|     Log.d(TAG, msg); | ||||
| @@ -460,22 +483,20 @@ public class AppRTCDemoActivity extends Activity | ||||
|   } | ||||
|  | ||||
|   // -----Implementation of AppRTCClient.AppRTCSignalingEvents --------------- | ||||
|   // All events are called from UI thread. | ||||
|   @Override | ||||
|   public void onConnectedToRoom(final SignalingParameters params) { | ||||
|     if (audioManager != null) { | ||||
|       // Store existing audio settings and change audio mode to | ||||
|       // MODE_IN_COMMUNICATION for best possible VoIP performance. | ||||
|       Log.d(TAG, "Initializing the audio manager..."); | ||||
|       audioManager.init(); | ||||
|     } | ||||
|   // All callbacks are invoked from websocket signaling looper thread and | ||||
|   // are routed to UI thread. | ||||
|   private void onConnectedToRoomInternal(final SignalingParameters params) { | ||||
|     signalingParameters = params; | ||||
|     abortUnless(PeerConnectionFactory.initializeAndroidGlobals( | ||||
|       this, true, true, hwCodec, VideoRendererGui.getEGLContext()), | ||||
|         "Failed to initializeAndroidGlobals"); | ||||
|     logAndToast("Creating peer connection..."); | ||||
|     pc = new PeerConnectionClient(localRender, remoteRender, | ||||
|         signalingParameters, this, startBitrate); | ||||
|     if (pc == null) { | ||||
|       // Create peer connection factory if render EGL context ready event | ||||
|       // has not been fired yet. | ||||
|       pc = new PeerConnectionClient(); | ||||
|       pc.createPeerConnectionFactory( | ||||
|           this, hwCodec, VideoRendererGui.getEGLContext(), this); | ||||
|     } | ||||
|     pc.createPeerConnection( | ||||
|         localRender, remoteRender, signalingParameters, startBitrate); | ||||
|     if (pc.isHDVideo()) { | ||||
|       setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); | ||||
|     } else { | ||||
| @@ -510,7 +531,7 @@ public class AppRTCDemoActivity extends Activity | ||||
|             } | ||||
|           }, null); | ||||
|         if (!success) { | ||||
|           throw new RuntimeException("getStats() return false!"); | ||||
|           Log.e(TAG, "getStats() return false!"); | ||||
|         } | ||||
|       } | ||||
|     }; | ||||
| @@ -524,75 +545,127 @@ public class AppRTCDemoActivity extends Activity | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onConnectedToRoom(final SignalingParameters params) { | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         onConnectedToRoomInternal(params); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onRemoteDescription(final SessionDescription sdp) { | ||||
|     if (pc == null) { | ||||
|       return; | ||||
|     } | ||||
|     logAndToast("Received remote " + sdp.type + " ..."); | ||||
|     pc.setRemoteDescription(sdp); | ||||
|     if (!signalingParameters.initiator) { | ||||
|       logAndToast("Creating ANSWER..."); | ||||
|       // Create answer. Answer SDP will be sent to offering client in | ||||
|       // PeerConnectionEvents.onLocalDescription event. | ||||
|       pc.createAnswer(); | ||||
|     } | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (pc == null) { | ||||
|           return; | ||||
|         } | ||||
|         logAndToast("Received remote " + sdp.type + " ..."); | ||||
|         pc.setRemoteDescription(sdp); | ||||
|         if (!signalingParameters.initiator) { | ||||
|           logAndToast("Creating ANSWER..."); | ||||
|           // Create answer. Answer SDP will be sent to offering client in | ||||
|           // PeerConnectionEvents.onLocalDescription event. | ||||
|           pc.createAnswer(); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onRemoteIceCandidate(final IceCandidate candidate) { | ||||
|     if (pc != null) { | ||||
|       pc.addRemoteIceCandidate(candidate); | ||||
|     } | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (pc != null) { | ||||
|           pc.addRemoteIceCandidate(candidate); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onChannelClose() { | ||||
|     logAndToast("Remote end hung up; dropping PeerConnection"); | ||||
|     disconnect(); | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         logAndToast("Remote end hung up; dropping PeerConnection"); | ||||
|         disconnect(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onChannelError(final String description) { | ||||
|     if (!isError) { | ||||
|       isError = true; | ||||
|       disconnectWithErrorMessage(description); | ||||
|     } | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (!isError) { | ||||
|           isError = true; | ||||
|           disconnectWithErrorMessage(description); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   // -----Implementation of PeerConnectionClient.PeerConnectionEvents.--------- | ||||
|   // Send local peer connection SDP and ICE candidates to remote party. | ||||
|   // All callbacks are invoked from UI thread. | ||||
|   // All callbacks are invoked from peer connection client looper thread and | ||||
|   // are routed to UI thread. | ||||
|   @Override | ||||
|   public void onLocalDescription(final SessionDescription sdp) { | ||||
|     if (appRtcClient != null) { | ||||
|       logAndToast("Sending " + sdp.type + " ..."); | ||||
|       if (signalingParameters.initiator) { | ||||
|         appRtcClient.sendOfferSdp(sdp); | ||||
|       } else { | ||||
|         appRtcClient.sendAnswerSdp(sdp); | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (appRtcClient != null) { | ||||
|           logAndToast("Sending " + sdp.type + " ..."); | ||||
|           if (signalingParameters.initiator) { | ||||
|             appRtcClient.sendOfferSdp(sdp); | ||||
|           } else { | ||||
|             appRtcClient.sendAnswerSdp(sdp); | ||||
|           } | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onIceCandidate(final IceCandidate candidate) { | ||||
|     if (appRtcClient != null) { | ||||
|       appRtcClient.sendLocalIceCandidate(candidate); | ||||
|     } | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (appRtcClient != null) { | ||||
|           appRtcClient.sendLocalIceCandidate(candidate); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onIceConnected() { | ||||
|     logAndToast("ICE connected"); | ||||
|     iceConnected = true; | ||||
|     updateVideoView(); | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         logAndToast("ICE connected"); | ||||
|         iceConnected = true; | ||||
|         updateVideoView(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onIceDisconnected() { | ||||
|     logAndToast("ICE disconnected"); | ||||
|     disconnect(); | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         logAndToast("ICE disconnected"); | ||||
|         iceConnected = false; | ||||
|         disconnect(); | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
| @@ -600,10 +673,15 @@ public class AppRTCDemoActivity extends Activity | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void onPeerConnectionError(String description) { | ||||
|     if (!isError) { | ||||
|       isError = true; | ||||
|       disconnectWithErrorMessage(description); | ||||
|     } | ||||
|   public void onPeerConnectionError(final String description) { | ||||
|     runOnUiThread(new Runnable() { | ||||
|       @Override | ||||
|       public void run() { | ||||
|         if (!isError) { | ||||
|           isError = true; | ||||
|           disconnectWithErrorMessage(description); | ||||
|         } | ||||
|       } | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 glaznev@webrtc.org
					glaznev@webrtc.org