Merging Henrik's and Peter's changes for AppRTCDemo
from https://github.com/hkjellander/AppRTCDemo. Description of changes: - Add connect screen with an option to enter room number or select loopback mode. - Add 'hangup' and 'WebRTC statistics' buttons to AppRTCDemo activity. BUG=3938 R=kjellander@webrtc.org, pbos@webrtc.org, pthatcher@webrtc.org Review URL: https://webrtc-codereview.appspot.com/28749004 git-svn-id: http://webrtc.googlecode.com/svn/trunk@7500 4adac7df-926f-26a2-2b94-8c16560cd09d
@@ -4,38 +4,40 @@
|
|||||||
android:versionCode="1"
|
android:versionCode="1"
|
||||||
android:versionName="1.0">
|
android:versionName="1.0">
|
||||||
|
|
||||||
<uses-feature android:name="android.hardware.camera" />
|
<uses-feature android:name="android.hardware.camera" />
|
||||||
<uses-feature android:name="android.hardware.camera.autofocus" />
|
<uses-feature android:name="android.hardware.camera.autofocus" />
|
||||||
<uses-feature android:glEsVersion="0x00020000" android:required="true"></uses-feature>
|
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
|
||||||
<uses-sdk android:minSdkVersion="13" android:targetSdkVersion="17" />
|
<uses-sdk android:minSdkVersion="13" android:targetSdkVersion="17" />
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.CAMERA"></uses-permission>
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
<uses-permission android:name="android.permission.INTERNET" />
|
<uses-permission android:name="android.permission.INTERNET" />
|
||||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||||
|
|
||||||
<application android:label="@string/app_name"
|
<application android:label="@string/app_name"
|
||||||
android:icon="@drawable/ic_launcher"
|
android:icon="@drawable/ic_launcher"
|
||||||
android:debuggable="true"
|
android:allowBackup="false">
|
||||||
android:allowBackup="false">
|
<activity android:name="ConnectActivity"
|
||||||
<activity android:name="AppRTCDemoActivity"
|
android:label="@string/app_name">
|
||||||
android:label="@string/app_name"
|
<intent-filter>
|
||||||
android:screenOrientation="fullUser"
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
android:configChanges="orientation|screenSize"
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
|
</intent-filter>
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
|
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.VIEW" />
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
<data android:scheme="https" android:host="apprtc.appspot.com" />
|
<data android:scheme="https" android:host="apprtc.appspot.com"/>
|
||||||
<data android:scheme="http" android:host="apprtc.appspot.com" />
|
<data android:scheme="http" android:host="apprtc.appspot.com"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
</application>
|
<activity android:name="AppRTCDemoActivity"
|
||||||
|
android:label="@string/app_name"
|
||||||
|
android:screenOrientation="fullUser"
|
||||||
|
android:configChanges="orientation|screenSize"
|
||||||
|
android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen">
|
||||||
|
</activity>
|
||||||
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
BIN
talk/examples/android/res/drawable-hdpi/disconnect.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 2.4 KiB |
BIN
talk/examples/android/res/drawable-ldpi/disconnect.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
talk/examples/android/res/drawable-mdpi/disconnect.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 1.7 KiB |
BIN
talk/examples/android/res/drawable-xhdpi/disconnect.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 3.3 KiB |
55
talk/examples/android/res/layout/activity_connect.xml
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:weightSum="1"
|
||||||
|
android:layout_margin="8dp"
|
||||||
|
android:layout_centerHorizontal="true">
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/apprtc_url"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:id="@+id/url_edittext"
|
||||||
|
android:inputType="textWebEmailAddress"
|
||||||
|
android:text="https://apprtc.appspot.com"
|
||||||
|
android:imeOptions="actionNext"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="5dp"
|
||||||
|
android:lines="1"
|
||||||
|
android:maxLines="1"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/room_name"/>
|
||||||
|
<EditText
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:id="@+id/room_edittext"
|
||||||
|
android:imeOptions="actionGo"/>
|
||||||
|
<TextView
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:layout_margin="5dp"
|
||||||
|
android:text="@string/room_description"/>
|
||||||
|
<CheckBox
|
||||||
|
android:id="@+id/check_loopback"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||||
|
android:text="@string/loopback_text" />
|
||||||
|
<Button
|
||||||
|
android:id="@+id/connect_button"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/connect_text"
|
||||||
|
android:textAppearance="?android:attr/textAppearanceLarge" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
33
talk/examples/android/res/layout/activity_fullscreen.xml
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<android.opengl.GLSurfaceView
|
||||||
|
android:id="@+id/glview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/room_name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_above="@+id/menubar_fragment"
|
||||||
|
android:textSize="24sp"
|
||||||
|
android:layout_margin="8dp"/>
|
||||||
|
<fragment
|
||||||
|
android:name="org.appspot.apprtc.AppRTCDemoActivity$MenuBarFragment"
|
||||||
|
android:id="@+id/menubar_fragment"
|
||||||
|
android:layout_centerHorizontal="true"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_alignParentBottom="true"
|
||||||
|
android:layout_marginBottom="32dp"
|
||||||
|
tools:layout="@layout/fragment_menubar"/>
|
||||||
|
|
||||||
|
</RelativeLayout>
|
||||||
28
talk/examples/android/res/layout/fragment_menubar.xml
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
tools:context="org.appspot.apprtc.AppRTCDemoActivity$MenuBarFragment"
|
||||||
|
android:id="@+id/menubar"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_gravity="center_vertical|center_horizontal">
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/button_disconnect"
|
||||||
|
android:background="@drawable/disconnect"
|
||||||
|
android:contentDescription="@string/disconnect_call"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"/>
|
||||||
|
|
||||||
|
<!-- TODO(kjellander): Add audio and video mute buttons. -->
|
||||||
|
|
||||||
|
<ImageButton
|
||||||
|
android:id="@+id/button_toggle_debug"
|
||||||
|
android:background="@android:drawable/ic_menu_info_details"
|
||||||
|
android:contentDescription="@string/disconnect_call"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="48dp"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -1,4 +1,19 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">AppRTC</string>
|
<string name="app_name" translatable="no">AppRTC</string>
|
||||||
|
<string name="disconnect_call">Disconnect Call</string>
|
||||||
|
<string name="apprtc_url">URL:</string>
|
||||||
|
<string name="room_name">Room name:</string>
|
||||||
|
<string name="room_description">
|
||||||
|
Please enter a room name. Room names are shared with everyone, so think
|
||||||
|
of something unique and send it to a friend.
|
||||||
|
</string>
|
||||||
|
<string name="connect_text">Connect</string>
|
||||||
|
<string name="loopback_text">Loopback connection</string>
|
||||||
|
<string name="invalid_url_title">Invalid URL</string>
|
||||||
|
<string name="invalid_url_text">The URL or room name you entered resulted in an invalid URL: %1$s
|
||||||
|
</string>
|
||||||
|
<string name="connecting_to">Connecting to: %1$s</string>
|
||||||
|
<string name="missing_url">FATAL ERROR: Missing URL to connect to.</string>
|
||||||
|
<string name="ok">OK</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -29,19 +29,24 @@ package org.appspot.apprtc;
|
|||||||
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
|
import android.app.Fragment;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Point;
|
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.opengl.GLSurfaceView;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.TypedValue;
|
import android.util.TypedValue;
|
||||||
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
|
import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageButton;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
@@ -66,13 +71,16 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
private PeerConnectionClient pc;
|
private PeerConnectionClient pc;
|
||||||
private AppRTCClient appRtcClient = new GAERTCClient(this, this);
|
private AppRTCClient appRtcClient = new GAERTCClient(this, this);
|
||||||
private AppRTCSignalingParameters appRtcParameters;
|
private AppRTCSignalingParameters appRtcParameters;
|
||||||
private AppRTCGLView vsv;
|
private View rootView;
|
||||||
|
private View menuBar;
|
||||||
|
private GLSurfaceView videoView;
|
||||||
private VideoRenderer.Callbacks localRender;
|
private VideoRenderer.Callbacks localRender;
|
||||||
private VideoRenderer.Callbacks remoteRender;
|
private VideoRenderer.Callbacks remoteRender;
|
||||||
private Toast logToast;
|
private Toast logToast;
|
||||||
private final LayoutParams hudLayout =
|
private final LayoutParams hudLayout =
|
||||||
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
|
||||||
private TextView hudView;
|
private TextView hudView;
|
||||||
|
private TextView roomName;
|
||||||
// Synchronize on quit[0] to avoid teardown-related crashes.
|
// Synchronize on quit[0] to avoid teardown-related crashes.
|
||||||
private final Boolean[] quit = new Boolean[] { false };
|
private final Boolean[] quit = new Boolean[] { false };
|
||||||
|
|
||||||
@@ -80,29 +88,66 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
public void onCreate(Bundle savedInstanceState) {
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// Set window styles for fullscreen-window size. Needs to be done before
|
||||||
|
// adding content.
|
||||||
|
requestWindowFeature(Window.FEATURE_NO_TITLE);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||||
|
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
||||||
|
getWindow().getDecorView().setSystemUiVisibility(
|
||||||
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
||||||
|
View.SYSTEM_UI_FLAG_FULLSCREEN |
|
||||||
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_fullscreen);
|
||||||
|
|
||||||
Thread.setDefaultUncaughtExceptionHandler(
|
Thread.setDefaultUncaughtExceptionHandler(
|
||||||
new UnhandledExceptionHandler(this));
|
new UnhandledExceptionHandler(this));
|
||||||
|
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
rootView = findViewById(android.R.id.content);
|
||||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
|
menuBar = findViewById(R.id.menubar_fragment);
|
||||||
|
roomName = (TextView) findViewById(R.id.room_name);
|
||||||
|
videoView = (GLSurfaceView) findViewById(R.id.glview);
|
||||||
|
|
||||||
Point displaySize = new Point();
|
VideoRendererGui.setView(videoView);
|
||||||
getWindowManager().getDefaultDisplay().getRealSize(displaySize);
|
|
||||||
|
|
||||||
vsv = new AppRTCGLView(this, displaySize);
|
|
||||||
VideoRendererGui.setView(vsv);
|
|
||||||
remoteRender = VideoRendererGui.create(0, 0, 100, 100,
|
remoteRender = VideoRendererGui.create(0, 0, 100, 100,
|
||||||
VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
|
VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
|
||||||
localRender = VideoRendererGui.create(0, 0, 100, 100,
|
localRender = VideoRendererGui.create(0, 0, 100, 100,
|
||||||
VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
|
VideoRendererGui.ScalingType.SCALE_ASPECT_FIT);
|
||||||
|
|
||||||
vsv.setOnClickListener(new View.OnClickListener() {
|
videoView.setOnClickListener(
|
||||||
@Override public void onClick(View v) {
|
new View.OnClickListener() {
|
||||||
toggleHUD();
|
@Override
|
||||||
}
|
public void onClick(View view) {
|
||||||
});
|
int visibility = menuBar.getVisibility() == View.VISIBLE
|
||||||
setContentView(vsv);
|
? View.INVISIBLE : View.VISIBLE;
|
||||||
logAndToast("Tap the screen to toggle stats visibility");
|
menuBar.setVisibility(visibility);
|
||||||
|
roomName.setVisibility(visibility);
|
||||||
|
if (visibility == View.VISIBLE) {
|
||||||
|
menuBar.bringToFront();
|
||||||
|
roomName.bringToFront();
|
||||||
|
rootView.invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
((ImageButton) findViewById(R.id.button_disconnect)).setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
logAndToast("Disconnecting call.");
|
||||||
|
disconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
((ImageButton) findViewById(R.id.button_toggle_debug)).setOnClickListener(
|
||||||
|
new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
int visibility = hudView.getVisibility() == View.VISIBLE
|
||||||
|
? View.INVISIBLE : View.VISIBLE;
|
||||||
|
hudView.setVisibility(visibility);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
hudView = new TextView(this);
|
hudView = new TextView(this);
|
||||||
hudView.setTextColor(Color.BLACK);
|
hudView.setTextColor(Color.BLACK);
|
||||||
@@ -123,17 +168,40 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
audioManager.setSpeakerphoneOn(!isWiredHeadsetOn);
|
audioManager.setSpeakerphoneOn(!isWiredHeadsetOn);
|
||||||
|
|
||||||
final Intent intent = getIntent();
|
final Intent intent = getIntent();
|
||||||
if ("android.intent.action.VIEW".equals(intent.getAction())) {
|
Uri url = intent.getData();
|
||||||
connectToRoom(intent.getData().toString());
|
if (url != null) {
|
||||||
return;
|
String room = url.getQueryParameter("r");
|
||||||
|
String loopback = url.getQueryParameter("debug");
|
||||||
|
if ((room != null && !room.equals("")) ||
|
||||||
|
(loopback != null && loopback.equals("loopback"))) {
|
||||||
|
logAndToast(getString(R.string.connecting_to, url));
|
||||||
|
appRtcClient.connectToRoom(url.toString());
|
||||||
|
roomName.setText(room);
|
||||||
|
} else {
|
||||||
|
logAndToast("Empty or missing room name!");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
logAndToast(getString(R.string.missing_url));
|
||||||
|
Log.wtf(TAG, "Didn't get any URL in intent!");
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MenuBarFragment extends Fragment {
|
||||||
|
@Override
|
||||||
|
public View onCreateView(
|
||||||
|
LayoutInflater inflater,
|
||||||
|
ViewGroup container,
|
||||||
|
Bundle savedInstanceState) {
|
||||||
|
return inflater.inflate(R.layout.fragment_menubar, container, false);
|
||||||
}
|
}
|
||||||
showGetRoomUI();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onPause() {
|
public void onPause() {
|
||||||
super.onPause();
|
super.onPause();
|
||||||
vsv.onPause();
|
videoView.onPause();
|
||||||
if (pc != null) {
|
if (pc != null) {
|
||||||
pc.stopVideoSource();
|
pc.stopVideoSource();
|
||||||
}
|
}
|
||||||
@@ -142,59 +210,18 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
vsv.onResume();
|
videoView.onResume();
|
||||||
if (pc != null) {
|
if (pc != null) {
|
||||||
pc.startVideoSource();
|
pc.startVideoSource();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onConfigurationChanged (Configuration newConfig) {
|
|
||||||
Point displaySize = new Point();
|
|
||||||
getWindowManager().getDefaultDisplay().getSize(displaySize);
|
|
||||||
vsv.updateDisplaySize(displaySize);
|
|
||||||
super.onConfigurationChanged(newConfig);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onDestroy() {
|
protected void onDestroy() {
|
||||||
disconnectAndExit();
|
disconnect();
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showGetRoomUI() {
|
|
||||||
final EditText roomInput = new EditText(this);
|
|
||||||
roomInput.setText("https://apprtc.appspot.com/?r=");
|
|
||||||
roomInput.setSelection(roomInput.getText().length());
|
|
||||||
DialogInterface.OnClickListener listener =
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
abortUnless(which == DialogInterface.BUTTON_POSITIVE, "lolwat?");
|
|
||||||
dialog.dismiss();
|
|
||||||
connectToRoom(roomInput.getText().toString());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
|
||||||
builder
|
|
||||||
.setMessage("Enter room URL").setView(roomInput)
|
|
||||||
.setPositiveButton("Go!", listener).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void connectToRoom(String roomUrl) {
|
|
||||||
logAndToast("Connecting to room...");
|
|
||||||
appRtcClient.connectToRoom(roomUrl);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Toggle visibility of the heads-up display.
|
|
||||||
private void toggleHUD() {
|
|
||||||
if (hudView.getVisibility() == View.VISIBLE) {
|
|
||||||
hudView.setVisibility(View.INVISIBLE);
|
|
||||||
} else {
|
|
||||||
hudView.setVisibility(View.VISIBLE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the heads-up display with information from |reports|.
|
// Update the heads-up display with information from |reports|.
|
||||||
private void updateHUD(StatsReport[] reports) {
|
private void updateHUD(StatsReport[] reports) {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
@@ -243,7 +270,7 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect from remote resources, dispose of local resources, and exit.
|
// Disconnect from remote resources, dispose of local resources, and exit.
|
||||||
private void disconnectAndExit() {
|
private void disconnect() {
|
||||||
synchronized (quit[0]) {
|
synchronized (quit[0]) {
|
||||||
if (quit[0]) {
|
if (quit[0]) {
|
||||||
return;
|
return;
|
||||||
@@ -300,7 +327,7 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
}
|
}
|
||||||
final Runnable runnableThis = this;
|
final Runnable runnableThis = this;
|
||||||
if (hudView.getVisibility() == View.INVISIBLE) {
|
if (hudView.getVisibility() == View.INVISIBLE) {
|
||||||
vsv.postDelayed(runnableThis, 1000);
|
videoView.postDelayed(runnableThis, 1000);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
boolean success = finalPC.getStats(new StatsObserver() {
|
boolean success = finalPC.getStats(new StatsObserver() {
|
||||||
@@ -313,7 +340,7 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
for (StatsReport report : reports) {
|
for (StatsReport report : reports) {
|
||||||
Log.d(TAG, "Stats: " + report.toString());
|
Log.d(TAG, "Stats: " + report.toString());
|
||||||
}
|
}
|
||||||
vsv.postDelayed(runnableThis, 1000);
|
videoView.postDelayed(runnableThis, 1000);
|
||||||
}
|
}
|
||||||
}, null);
|
}, null);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
@@ -322,7 +349,7 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
vsv.postDelayed(repeatedStatsLogger, 1000);
|
videoView.postDelayed(repeatedStatsLogger, 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
logAndToast("Waiting for remote connection...");
|
logAndToast("Waiting for remote connection...");
|
||||||
@@ -358,13 +385,13 @@ public class AppRTCDemoActivity extends Activity
|
|||||||
@Override
|
@Override
|
||||||
public void onChannelClose() {
|
public void onChannelClose() {
|
||||||
logAndToast("Remote end hung up; dropping PeerConnection");
|
logAndToast("Remote end hung up; dropping PeerConnection");
|
||||||
disconnectAndExit();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onChannelError(int code, String description) {
|
public void onChannelError(int code, String description) {
|
||||||
logAndToast("Channel error: " + code + ". " + description);
|
logAndToast("Channel error: " + code + ". " + description);
|
||||||
disconnectAndExit();
|
disconnect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
|
// -----Implementation of PeerConnectionClient.PeerConnectionEvents.---------
|
||||||
|
|||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
* libjingle
|
|
||||||
* Copyright 2014, Google Inc.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
|
||||||
* this list of conditions and the following disclaimer in the documentation
|
|
||||||
* and/or other materials provided with the distribution.
|
|
||||||
* 3. The name of the author may not be used to endorse or promote products
|
|
||||||
* derived from this software without specific prior written permission.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
|
||||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
|
||||||
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
|
||||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
||||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
|
||||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
|
||||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.appspot.apprtc;
|
|
||||||
|
|
||||||
import android.content.Context;
|
|
||||||
import android.graphics.Point;
|
|
||||||
import android.opengl.GLSurfaceView;
|
|
||||||
|
|
||||||
public class AppRTCGLView extends GLSurfaceView {
|
|
||||||
private Point screenDimensions;
|
|
||||||
|
|
||||||
public AppRTCGLView(Context c, Point screenDimensions) {
|
|
||||||
super(c);
|
|
||||||
this.screenDimensions = screenDimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void updateDisplaySize(Point screenDimensions) {
|
|
||||||
this.screenDimensions = screenDimensions;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onMeasure(int unusedX, int unusedY) {
|
|
||||||
// Go big or go home!
|
|
||||||
setMeasuredDimension(screenDimensions.x, screenDimensions.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void onAttachedToWindow() {
|
|
||||||
super.onAttachedToWindow();
|
|
||||||
setSystemUiVisibility(SYSTEM_UI_FLAG_HIDE_NAVIGATION |
|
|
||||||
SYSTEM_UI_FLAG_FULLSCREEN | SYSTEM_UI_FLAG_IMMERSIVE_STICKY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
/*
|
||||||
|
* libjingle
|
||||||
|
* Copyright 2014, Google Inc.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.appspot.apprtc;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.webkit.URLUtil;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CheckBox;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the initial setup where the user selects which room to join.
|
||||||
|
*/
|
||||||
|
public class ConnectActivity extends Activity {
|
||||||
|
|
||||||
|
private static final String TAG = "ConnectActivity";
|
||||||
|
public static final String CONNECT_URL_EXTRA = "connect_url";
|
||||||
|
private Button connectButton;
|
||||||
|
private EditText urlEditText;
|
||||||
|
private EditText roomEditText;
|
||||||
|
private CheckBox loopbackCheckBox;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
|
// If an implicit VIEW intent is launching the app, go directly to that URL.
|
||||||
|
final Intent intent = getIntent();
|
||||||
|
if ("android.intent.action.VIEW".equals(intent.getAction())) {
|
||||||
|
connectToRoom(intent.getData().toString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setContentView(R.layout.activity_connect);
|
||||||
|
|
||||||
|
urlEditText = (EditText) findViewById(R.id.url_edittext);
|
||||||
|
|
||||||
|
loopbackCheckBox = (CheckBox) findViewById(R.id.check_loopback);
|
||||||
|
loopbackCheckBox.setChecked(false);
|
||||||
|
|
||||||
|
roomEditText = (EditText) findViewById(R.id.room_edittext);
|
||||||
|
roomEditText.setOnEditorActionListener(
|
||||||
|
new TextView.OnEditorActionListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onEditorAction(
|
||||||
|
TextView textView, int i, KeyEvent keyEvent) {
|
||||||
|
if (i == EditorInfo.IME_ACTION_GO) {
|
||||||
|
connectButton.performClick();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
roomEditText.requestFocus();
|
||||||
|
|
||||||
|
connectButton = (Button) findViewById(R.id.connect_button);
|
||||||
|
connectButton.setOnClickListener(new OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
String url = urlEditText.getText().toString();
|
||||||
|
if (loopbackCheckBox.isChecked()) {
|
||||||
|
url += "/?debug=loopback";
|
||||||
|
} else {
|
||||||
|
url += "/?r=" + roomEditText.getText();
|
||||||
|
}
|
||||||
|
// TODO(kjellander): Add support for custom parameters to the URL.
|
||||||
|
connectToRoom(url);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void connectToRoom(String roomUrl) {
|
||||||
|
if (validateUrl(roomUrl)) {
|
||||||
|
Uri url = Uri.parse(roomUrl);
|
||||||
|
Intent intent = new Intent(this, AppRTCDemoActivity.class);
|
||||||
|
intent.setData(url);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean validateUrl(String url) {
|
||||||
|
if (URLUtil.isHttpsUrl(url) || URLUtil.isHttpUrl(url))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
new AlertDialog.Builder(this)
|
||||||
|
.setTitle(getText(R.string.invalid_url_title))
|
||||||
|
.setMessage(getString(R.string.invalid_url_text, url))
|
||||||
|
.setCancelable(false)
|
||||||
|
.setNeutralButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int id) {
|
||||||
|
dialog.cancel();
|
||||||
|
}
|
||||||
|
}).create().show();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -318,13 +318,20 @@
|
|||||||
'examples/android/jni/Android.mk',
|
'examples/android/jni/Android.mk',
|
||||||
'examples/android/project.properties',
|
'examples/android/project.properties',
|
||||||
'examples/android/res/drawable-hdpi/ic_launcher.png',
|
'examples/android/res/drawable-hdpi/ic_launcher.png',
|
||||||
|
'examples/android/res/drawable-hdpi/disconnect.png',
|
||||||
'examples/android/res/drawable-ldpi/ic_launcher.png',
|
'examples/android/res/drawable-ldpi/ic_launcher.png',
|
||||||
|
'examples/android/res/drawable-ldpi/disconnect.png',
|
||||||
'examples/android/res/drawable-mdpi/ic_launcher.png',
|
'examples/android/res/drawable-mdpi/ic_launcher.png',
|
||||||
|
'examples/android/res/drawable-mdpi/disconnect.png',
|
||||||
'examples/android/res/drawable-xhdpi/ic_launcher.png',
|
'examples/android/res/drawable-xhdpi/ic_launcher.png',
|
||||||
|
'examples/android/res/drawable-xhdpi/disconnect.png',
|
||||||
|
'examples/android/res/layout/activity_connect.xml',
|
||||||
|
'examples/android/res/layout/activity_fullscreen.xml',
|
||||||
|
'examples/android/res/layout/fragment_menubar.xml',
|
||||||
'examples/android/res/values/strings.xml',
|
'examples/android/res/values/strings.xml',
|
||||||
'examples/android/src/org/appspot/apprtc/AppRTCClient.java',
|
'examples/android/src/org/appspot/apprtc/AppRTCClient.java',
|
||||||
'examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java',
|
'examples/android/src/org/appspot/apprtc/AppRTCDemoActivity.java',
|
||||||
'examples/android/src/org/appspot/apprtc/AppRTCGLView.java',
|
'examples/android/src/org/appspot/apprtc/ConnectActivity.java',
|
||||||
'examples/android/src/org/appspot/apprtc/GAEChannelClient.java',
|
'examples/android/src/org/appspot/apprtc/GAEChannelClient.java',
|
||||||
'examples/android/src/org/appspot/apprtc/GAERTCClient.java',
|
'examples/android/src/org/appspot/apprtc/GAERTCClient.java',
|
||||||
'examples/android/src/org/appspot/apprtc/PeerConnectionClient.java',
|
'examples/android/src/org/appspot/apprtc/PeerConnectionClient.java',
|
||||||
|
|||||||