/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of linphone-android
* (see https://www.linphone.org).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package org.linphone.settings;
import android.Manifest;
import android.os.Bundle;
import android.text.InputType;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
import java.util.ArrayList;
import java.util.List;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.core.Core;
import org.linphone.core.Factory;
import org.linphone.core.PayloadType;
import org.linphone.core.VideoDefinition;
import org.linphone.core.tools.Log;
import org.linphone.mediastream.Version;
import org.linphone.settings.widget.ListSetting;
import org.linphone.settings.widget.SettingListenerBase;
import org.linphone.settings.widget.SwitchSetting;
import org.linphone.settings.widget.TextSetting;
public class VideoSettingsFragment extends SettingsFragment {
private View mRootView;
private LinphonePreferences mPrefs;
private SwitchSetting mEnable, mAutoInitiate, mAutoAccept, mOverlay, mVideoPreview;
private ListSetting mPreset, mSize, mFps;
private TextSetting mBandwidth;
private LinearLayout mVideoCodecs;
private TextView mVideoCodecsHeader;
private ListSetting mCameraDevices;
@Nullable
@Override
public View onCreateView(
LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.settings_video, container, false);
loadSettings();
return mRootView;
}
@Override
public void onResume() {
super.onResume();
mPrefs = LinphonePreferences.instance();
updateValues();
}
private void loadSettings() {
mEnable = mRootView.findViewById(R.id.pref_video_enable);
mVideoPreview = mRootView.findViewById(R.id.pref_video_preview);
mAutoInitiate = mRootView.findViewById(R.id.pref_video_initiate_call_with_video);
mAutoAccept = mRootView.findViewById(R.id.pref_video_automatically_accept_video);
mCameraDevices = mRootView.findViewById(R.id.pref_video_camera_device);
initCameraDevicesList();
mOverlay = mRootView.findViewById(R.id.pref_overlay);
mPreset = mRootView.findViewById(R.id.pref_video_preset);
mSize = mRootView.findViewById(R.id.pref_preferred_video_size);
initVideoSizeList();
mFps = mRootView.findViewById(R.id.pref_preferred_fps);
initFpsList();
mBandwidth = mRootView.findViewById(R.id.pref_bandwidth_limit);
mBandwidth.setInputType(InputType.TYPE_CLASS_NUMBER);
mVideoCodecs = mRootView.findViewById(R.id.pref_video_codecs);
mVideoCodecsHeader = mRootView.findViewById(R.id.pref_video_codecs_header);
}
private void setListeners() {
mEnable.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableVideo(newValue);
if (!newValue) {
mVideoPreview.setChecked(false);
mAutoAccept.setChecked(false);
mAutoInitiate.setChecked(false);
}
updateVideoSettingsVisibility(newValue);
}
});
mVideoPreview.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
if (newValue) {
if (!((SettingsActivity) getActivity())
.checkPermission(Manifest.permission.CAMERA)) {
((SettingsActivity) getActivity())
.requestPermissionIfNotGranted(Manifest.permission.CAMERA);
} else {
mPrefs.setVideoPreviewEnabled(true);
}
} else {
mPrefs.setVideoPreviewEnabled(false);
}
}
});
mAutoInitiate.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setInitiateVideoCall(newValue);
}
});
mAutoAccept.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.setAutomaticallyAcceptVideoRequests(newValue);
}
});
mCameraDevices.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setCameraDevice(newValue);
}
});
mOverlay.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
mPrefs.enableOverlay(
newValue
&& ((SettingsActivity) getActivity())
.checkAndRequestOverlayPermission());
}
});
mPreset.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setVideoPreset(newValue);
mFps.setVisibility(newValue.equals("custom") ? View.VISIBLE : View.GONE);
mBandwidth.setVisibility(
newValue.equals("custom") ? View.VISIBLE : View.GONE);
}
});
mSize.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
mPrefs.setPreferredVideoSize(newValue);
}
});
mFps.setListener(
new SettingListenerBase() {
@Override
public void onListValueChanged(int position, String newLabel, String newValue) {
try {
mPrefs.setPreferredVideoFps(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
mBandwidth.setListener(
new SettingListenerBase() {
@Override
public void onTextValueChanged(String newValue) {
try {
mPrefs.setBandwidthLimit(Integer.valueOf(newValue));
} catch (NumberFormatException nfe) {
Log.e(nfe);
}
}
});
}
private void updateValues() {
mEnable.setChecked(mPrefs.isVideoEnabled());
updateVideoSettingsVisibility(mPrefs.isVideoEnabled());
mVideoPreview.setChecked(mPrefs.isVideoPreviewEnabled());
mAutoInitiate.setChecked(mPrefs.shouldInitiateVideoCall());
mAutoAccept.setChecked(mPrefs.shouldAutomaticallyAcceptVideoRequests());
mCameraDevices.setValue(mPrefs.getCameraDevice());
mOverlay.setChecked(mPrefs.isOverlayEnabled());
if (Version.sdkAboveOrEqual(Version.API26_O_80)
&& getResources().getBoolean(R.bool.allow_pip_while_video_call)) {
// Disable overlay and use PIP feature
mOverlay.setVisibility(View.GONE);
}
mBandwidth.setValue(mPrefs.getBandwidthLimit());
mBandwidth.setVisibility(
mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE);
mPreset.setValue(mPrefs.getVideoPreset());
mSize.setValue(mPrefs.getPreferredVideoSize());
mFps.setValue(mPrefs.getPreferredVideoFps());
mFps.setVisibility(mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE);
populateVideoCodecs();
setListeners();
}
private void initVideoSizeList() {
List entries = new ArrayList<>();
List values = new ArrayList<>();
for (VideoDefinition vd : Factory.instance().getSupportedVideoDefinitions()) {
entries.add(vd.getName());
values.add(vd.getName());
}
mSize.setItems(entries, values);
}
private void initFpsList() {
List entries = new ArrayList<>();
List values = new ArrayList<>();
entries.add(getString(R.string.pref_none));
values.add("0");
for (int i = 5; i <= 30; i += 5) {
String str = Integer.toString(i);
entries.add(str);
values.add(str);
}
mFps.setItems(entries, values);
}
private void populateVideoCodecs() {
mVideoCodecs.removeAllViews();
Core core = LinphoneManager.getCore();
if (core != null) {
for (final PayloadType pt : core.getVideoPayloadTypes()) {
final SwitchSetting codec = new SwitchSetting(getActivity());
codec.setTitle(pt.getMimeType());
if (pt.enabled()) {
// Never use codec.setChecked(pt.enabled) !
codec.setChecked(true);
}
codec.setListener(
new SettingListenerBase() {
@Override
public void onBoolValueChanged(boolean newValue) {
pt.enable(newValue);
}
});
mVideoCodecs.addView(codec);
}
}
}
private void updateVideoSettingsVisibility(boolean show) {
mVideoPreview.setVisibility(
show
&& getResources().getBoolean(R.bool.isTablet)
&& getResources()
.getBoolean(R.bool.show_camera_preview_on_dialer_on_tablets)
? View.VISIBLE
: View.GONE);
mAutoInitiate.setVisibility(show ? View.VISIBLE : View.GONE);
mAutoAccept.setVisibility(show ? View.VISIBLE : View.GONE);
mCameraDevices.setVisibility(show ? View.VISIBLE : View.GONE);
mOverlay.setVisibility(show ? View.VISIBLE : View.GONE);
mBandwidth.setVisibility(show ? View.VISIBLE : View.GONE);
mPreset.setVisibility(show ? View.VISIBLE : View.GONE);
mSize.setVisibility(show ? View.VISIBLE : View.GONE);
mFps.setVisibility(show ? View.VISIBLE : View.GONE);
mVideoCodecs.setVisibility(show ? View.VISIBLE : View.GONE);
mVideoCodecsHeader.setVisibility(show ? View.VISIBLE : View.GONE);
if (show) {
if (Version.sdkAboveOrEqual(Version.API26_O_80)
&& getResources().getBoolean(R.bool.allow_pip_while_video_call)) {
// Disable overlay and use PIP feature
mOverlay.setVisibility(View.GONE);
}
mBandwidth.setVisibility(
mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE);
mFps.setVisibility(mPrefs.getVideoPreset().equals("custom") ? View.VISIBLE : View.GONE);
}
}
private void initCameraDevicesList() {
List entries = new ArrayList<>();
List values = new ArrayList<>();
Core core = LinphoneManager.getCore();
if (core != null) {
for (String camera : core.getVideoDevicesList()) {
entries.add(camera);
values.add(camera);
}
}
mCameraDevices.setItems(entries, values);
}
}