1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11package org.webrtc.webrtcdemo;
12
13import android.app.Activity;
14import android.app.Fragment;
15import android.os.Bundle;
16import android.util.Log;
17import android.view.LayoutInflater;
18import android.view.SurfaceView;
19import android.view.View;
20import android.view.ViewGroup;
21import android.widget.Button;
22import android.widget.LinearLayout;
23import android.widget.TextView;
24
25public class MainMenuFragment extends Fragment implements MediaEngineObserver {
26
27  private String TAG;
28  private MenuStateProvider stateProvider;
29
30  private Button btStartStopCall;
31  private TextView tvStats;
32
33  // Remote and local stream displays.
34  private LinearLayout llRemoteSurface;
35  private LinearLayout llLocalSurface;
36
37  @Override
38  public View onCreateView(LayoutInflater inflater, ViewGroup container,
39      Bundle savedInstanceState) {
40    View v = inflater.inflate(R.layout.mainmenu, container, false);
41
42    TAG = getResources().getString(R.string.tag);
43
44    llRemoteSurface = (LinearLayout) v.findViewById(R.id.llRemoteView);
45    llLocalSurface = (LinearLayout) v.findViewById(R.id.llLocalView);
46
47    Button btStats = (Button) v.findViewById(R.id.btStats);
48    boolean stats = getResources().getBoolean(R.bool.stats_enabled_default);
49    enableStats(btStats, stats);
50    btStats.setOnClickListener(new View.OnClickListener() {
51        public void onClick(View button) {
52          boolean turnOnStats = ((Button) button).getText().equals(
53              getResources().getString(R.string.statsOn));
54          enableStats((Button) button, turnOnStats);
55        }
56    });
57    tvStats = (TextView) v.findViewById(R.id.tvStats);
58
59    Button btSwitchCamera = (Button) v.findViewById(R.id.btSwitchCamera);
60    if (getEngine().hasMultipleCameras()) {
61      btSwitchCamera.setOnClickListener(new View.OnClickListener() {
62        public void onClick(View button) {
63          toggleCamera((Button) button);
64        }
65        });
66    } else {
67      btSwitchCamera.setEnabled(false);
68    }
69    btSwitchCamera.setText(getEngine().frontCameraIsSet() ?
70        R.string.backCamera :
71        R.string.frontCamera);
72
73    btStartStopCall = (Button) v.findViewById(R.id.btStartStopCall);
74    btStartStopCall.setText(getEngine().isRunning() ?
75        R.string.stopCall :
76        R.string.startCall);
77    btStartStopCall.setOnClickListener(new View.OnClickListener() {
78        public void onClick(View button) {
79          toggleStart();
80        }
81      });
82    return v;
83  }
84
85  @Override
86  public void onAttach(Activity activity) {
87    super.onAttach(activity);
88
89    // This makes sure that the container activity has implemented
90    // the callback interface. If not, it throws an exception.
91    try {
92      stateProvider = (MenuStateProvider) activity;
93    } catch (ClassCastException e) {
94      throw new ClassCastException(activity +
95          " must implement MenuStateProvider");
96    }
97  }
98
99  // tvStats need to be updated on the UI thread.
100  public void newStats(final String stats) {
101    getActivity().runOnUiThread(new Runnable() {
102        public void run() {
103          tvStats.setText(stats);
104        }
105      });
106  }
107
108  private MediaEngine getEngine() {
109    return stateProvider.getEngine();
110  }
111
112  private void setViews() {
113    SurfaceView remoteSurfaceView = getEngine().getRemoteSurfaceView();
114    if (remoteSurfaceView != null) {
115      llRemoteSurface.addView(remoteSurfaceView);
116    }
117    SurfaceView svLocal = getEngine().getLocalSurfaceView();
118    if (svLocal != null) {
119      llLocalSurface.addView(svLocal);
120    }
121  }
122
123  private void clearViews() {
124    SurfaceView remoteSurfaceView = getEngine().getRemoteSurfaceView();
125    if (remoteSurfaceView != null) {
126      llRemoteSurface.removeView(remoteSurfaceView);
127    }
128    SurfaceView svLocal = getEngine().getLocalSurfaceView();
129    if (svLocal != null) {
130      llLocalSurface.removeView(svLocal);
131    }
132  }
133
134  private void enableStats(Button btStats, boolean enable) {
135    if (enable) {
136      getEngine().setObserver(this);
137    } else {
138      getEngine().setObserver(null);
139      // Clear old stats text by posting empty stats.
140      newStats("");
141    }
142    // If stats was true it was just turned on. This means that
143    // clicking the button again should turn off stats.
144    btStats.setText(enable ? R.string.statsOff : R.string.statsOn);
145  }
146
147  private void toggleCamera(Button btSwitchCamera) {
148    SurfaceView svLocal = getEngine().getLocalSurfaceView();
149    boolean resetLocalView = svLocal != null;
150    if (resetLocalView) {
151      llLocalSurface.removeView(svLocal);
152    }
153    getEngine().toggleCamera();
154    if (resetLocalView) {
155      svLocal = getEngine().getLocalSurfaceView();
156      llLocalSurface.addView(svLocal);
157    }
158    btSwitchCamera.setText(getEngine().frontCameraIsSet() ?
159        R.string.backCamera :
160        R.string.frontCamera);
161  }
162
163  public void toggleStart() {
164    if (getEngine().isRunning()) {
165      stopAll();
166    } else {
167      startCall();
168    }
169    btStartStopCall.setText(getEngine().isRunning() ?
170        R.string.stopCall :
171        R.string.startCall);
172  }
173
174  public void stopAll() {
175    clearViews();
176    getEngine().stop();
177  }
178
179  private void startCall() {
180    getEngine().start();
181    setViews();
182  }
183}