aboutsummaryrefslogtreecommitdiff
path: root/webrtc/examples/android/media_demo/src/org/webrtc/webrtcdemo/WebRTCDemo.java
blob: 3b972cf1268866166b73fef7a1bf4d3d9741c456 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
/*
 *  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<T extends Fragment>
      implements ActionBar.TabListener {
    private Fragment fragment;
    private final Activity activity;
    private final String tag;
    private final Class<T> instance;
    private final Bundle args;

    public TabListener(Activity activity, String tag, Class<T> clz) {
      this(activity, tag, clz, null);
    }

    public TabListener(Activity activity, String tag, Class<T> 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.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));

    // 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<MainMenuFragment>(
            this, "main", MainMenuFragment.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
        .setText("Settings")
        .setTabListener(new TabListener<SettingsMenuFragment>(
            this, "Settings", SettingsMenuFragment.class));
    actionBar.addTab(tab);

    tab = actionBar.newTab()
        .setText("Audio")
        .setTabListener(new TabListener<AudioMenuFragment>(
            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());
      }
  };
}