/* * Copyright (c) 2013 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.webrtc.webrtcdemo; import android.app.ActionBar.Tab; import android.app.ActionBar.TabListener; import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; import android.app.FragmentTransaction; import android.content.pm.ActivityInfo; import android.media.AudioManager; import android.os.Bundle; import android.os.Handler; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.WindowManager; public class WebRTCDemo extends Activity implements MenuStateProvider { // From http://developer.android.com/guide/topics/ui/actionbar.html public static class TabListener implements ActionBar.TabListener { private Fragment fragment; private final Activity activity; private final String tag; private final Class instance; private final Bundle args; public TabListener(Activity activity, String tag, Class clz) { this(activity, tag, clz, null); } public TabListener(Activity activity, String tag, Class clz, Bundle args) { this.activity = activity; this.tag = tag; this.instance = clz; this.args = args; } public void onTabSelected(Tab tab, FragmentTransaction ft) { // Check if the fragment is already initialized if (fragment == null) { // If not, instantiate and add it to the activity fragment = Fragment.instantiate(activity, instance.getName(), args); ft.add(android.R.id.content, fragment, tag); } else { // If it exists, simply attach it in order to show it ft.attach(fragment); } } public void onTabUnselected(Tab tab, FragmentTransaction ft) { if (fragment != null) { // Detach the fragment, because another one is being attached ft.detach(fragment); } } public void onTabReselected(Tab tab, FragmentTransaction ft) { // User selected the already selected tab. Do nothing. } } private NativeWebRtcContextRegistry contextRegistry = null; private MediaEngine mediaEngine = null; private Handler handler; public MediaEngine getEngine() { return mediaEngine; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Global settings. getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); // State. // Must be instantiated before MediaEngine. contextRegistry = new NativeWebRtcContextRegistry(); contextRegistry.register(this); // Load all settings dictated in xml. mediaEngine = new MediaEngine(this); mediaEngine.setRemoteIp(getResources().getString(R.string.loopbackIp)); mediaEngine.setTrace(getResources().getBoolean( R.bool.trace_enabled_default)); mediaEngine.setAudio(getResources().getBoolean( R.bool.audio_enabled_default)); mediaEngine.setAudioCodec(mediaEngine.getIsacIndex()); mediaEngine.setAudioRxPort(getResources().getInteger( R.integer.aRxPortDefault)); mediaEngine.setAudioTxPort(getResources().getInteger( R.integer.aTxPortDefault)); mediaEngine.setSpeaker(getResources().getBoolean( R.bool.speaker_enabled_default)); mediaEngine.setDebuging(getResources().getBoolean( R.bool.apm_debug_enabled_default)); mediaEngine.setReceiveVideo(getResources().getBoolean( R.bool.video_receive_enabled_default)); mediaEngine.setSendVideo(getResources().getBoolean( R.bool.video_send_enabled_default)); mediaEngine.setVideoCodec(getResources().getInteger( R.integer.video_codec_default)); // TODO(hellner): resolutions should probably be in the xml as well. mediaEngine.setResolutionIndex(MediaEngine.numberOfResolutions() - 2); mediaEngine.setVideoTxPort(getResources().getInteger( R.integer.vTxPortDefault)); mediaEngine.setVideoRxPort(getResources().getInteger( R.integer.vRxPortDefault)); mediaEngine.setNack(getResources().getBoolean(R.bool.nack_enabled_default)); mediaEngine.setViewSelection(getResources().getInteger( R.integer.defaultView)); // Create action bar with all tabs. ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); actionBar.setDisplayShowTitleEnabled(false); Tab tab = actionBar.newTab() .setText("Main") .setTabListener(new TabListener( this, "main", MainMenuFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab() .setText("Settings") .setTabListener(new TabListener( this, "Settings", SettingsMenuFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab() .setText("Video") .setTabListener(new TabListener( this, "video", VideoMenuFragment.class)); actionBar.addTab(tab); tab = actionBar.newTab() .setText("Audio") .setTabListener(new TabListener( this, "Audio", AudioMenuFragment.class)); actionBar.addTab(tab); enableTimedStartStop(); // Hint that voice call audio stream should be used for hardware volume // controls. setVolumeControlStream(AudioManager.STREAM_VOICE_CALL); } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.main_activity_actions, menu); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle presses on the action bar items switch (item.getItemId()) { case R.id.action_exit: MainMenuFragment main = (MainMenuFragment)getFragmentManager() .findFragmentByTag("main"); main.stopAll(); finish(); return true; default: return super.onOptionsItemSelected(item); } } @Override public void onDestroy() { disableTimedStartStop(); mediaEngine.dispose(); contextRegistry.unRegister(); super.onDestroy(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // Prevent app from running in the background. MainMenuFragment main = (MainMenuFragment)getFragmentManager() .findFragmentByTag("main"); main.stopAll(); finish(); return true; } return super.onKeyDown(keyCode, event); } private int getCallRestartPeriodicity() { return getResources().getInteger(R.integer.call_restart_periodicity_ms); } // Thread repeatedly calling start/stop. void enableTimedStartStop() { if (getCallRestartPeriodicity() > 0) { // Periodicity == 0 <-> Disabled. handler = new Handler(); handler.postDelayed(startOrStopCallback, getCallRestartPeriodicity()); } } void disableTimedStartStop() { if (handler != null) { handler.removeCallbacks(startOrStopCallback); } } private Runnable startOrStopCallback = new Runnable() { public void run() { MainMenuFragment main = (MainMenuFragment)getFragmentManager() .findFragmentByTag("main"); main.toggleStart(); handler.postDelayed(startOrStopCallback, getCallRestartPeriodicity()); } }; }