/*
* 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.call;
import android.Manifest;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import java.util.ArrayList;
import org.linphone.LinphoneContext;
import org.linphone.LinphoneManager;
import org.linphone.R;
import org.linphone.activities.LinphoneGenericActivity;
import org.linphone.call.views.CallIncomingAnswerButton;
import org.linphone.call.views.CallIncomingButtonListener;
import org.linphone.call.views.CallIncomingDeclineButton;
import org.linphone.compatibility.Compatibility;
import org.linphone.contacts.ContactsManager;
import org.linphone.contacts.LinphoneContact;
import org.linphone.contacts.views.ContactAvatar;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.Call.State;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.tools.Log;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
public class CallIncomingActivity extends LinphoneGenericActivity {
private TextView mName, mNumber;
private Call mCall;
private CoreListenerStub mListener;
private boolean mAlreadyAcceptedOrDeniedCall;
private TextureView mVideoDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Compatibility.setShowWhenLocked(this, true);
Compatibility.setTurnScreenOn(this, true);
setContentView(R.layout.call_incoming);
mName = findViewById(R.id.contact_name);
mNumber = findViewById(R.id.contact_number);
mVideoDisplay = findViewById(R.id.videoSurface);
CallIncomingAnswerButton mAccept = findViewById(R.id.answer_button);
CallIncomingDeclineButton mDecline = findViewById(R.id.decline_button);
ImageView mAcceptIcon = findViewById(R.id.acceptIcon);
lookupCurrentCall();
if (LinphonePreferences.instance() != null
&& mCall != null
&& mCall.getRemoteParams() != null
&& LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()
&& mCall.getRemoteParams().videoEnabled()) {
mAcceptIcon.setImageResource(R.drawable.call_video_start);
}
KeyguardManager mKeyguardManager =
(KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
boolean doNotUseSliders =
getResources()
.getBoolean(
R.bool.do_not_use_sliders_to_answer_hangup_call_if_phone_unlocked);
if (doNotUseSliders && !mKeyguardManager.inKeyguardRestrictedInputMode()) {
mAccept.setSliderMode(false);
mDecline.setSliderMode(false);
} else {
mAccept.setSliderMode(true);
mDecline.setSliderMode(true);
mAccept.setDeclineButton(mDecline);
mDecline.setAnswerButton(mAccept);
}
mAccept.setListener(
new CallIncomingButtonListener() {
@Override
public void onAction() {
answer();
}
});
mDecline.setListener(
new CallIncomingButtonListener() {
@Override
public void onAction() {
decline();
}
});
mListener =
new CoreListenerStub() {
@Override
public void onCallStateChanged(
Core core, Call call, State state, String message) {
if (state == State.End || state == State.Released) {
mCall = null;
finish();
}
}
};
}
@Override
protected void onStart() {
super.onStart();
checkAndRequestCallPermissions();
}
@Override
protected void onResume() {
super.onResume();
Core core = LinphoneManager.getCore();
if (core != null) {
core.addListener(mListener);
}
mAlreadyAcceptedOrDeniedCall = false;
mCall = null;
// Only one call ringing at a time is allowed
lookupCurrentCall();
if (mCall == null) {
// The incoming call no longer exists.
Log.d("Couldn't find incoming call");
finish();
return;
}
Address address = mCall.getRemoteAddress();
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(address);
if (contact != null) {
ContactAvatar.displayAvatar(contact, findViewById(R.id.avatar_layout), true);
mName.setText(contact.getFullName());
} else {
String displayName = LinphoneUtils.getAddressDisplayName(address);
ContactAvatar.displayAvatar(displayName, findViewById(R.id.avatar_layout), true);
mName.setText(displayName);
}
mNumber.setText(address.asStringUriOnly());
if (LinphonePreferences.instance().acceptIncomingEarlyMedia()) {
if (mCall.getCurrentParams() != null && mCall.getCurrentParams().videoEnabled()) {
findViewById(R.id.avatar_layout).setVisibility(View.GONE);
mCall.getCore().setNativeVideoWindowId(mVideoDisplay);
}
}
}
@Override
protected void onPause() {
Core core = LinphoneManager.getCore();
if (core != null) {
core.removeListener(mListener);
}
super.onPause();
}
@Override
protected void onDestroy() {
mName = null;
mNumber = null;
mCall = null;
mListener = null;
mVideoDisplay = null;
super.onDestroy();
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (LinphoneContext.isReady()
&& (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_HOME)
&& mCall != null) {
mCall.terminate();
finish();
}
return super.onKeyDown(keyCode, event);
}
private void lookupCurrentCall() {
if (LinphoneManager.getCore() != null) {
for (Call call : LinphoneManager.getCore().getCalls()) {
if (State.IncomingReceived == call.getState()
|| State.IncomingEarlyMedia == call.getState()) {
mCall = call;
break;
}
}
}
}
private void decline() {
if (mAlreadyAcceptedOrDeniedCall) {
return;
}
mAlreadyAcceptedOrDeniedCall = true;
if (mCall != null) mCall.terminate();
finish();
}
private void answer() {
if (mAlreadyAcceptedOrDeniedCall) {
return;
}
mAlreadyAcceptedOrDeniedCall = true;
if (!LinphoneManager.getCallManager().acceptCall(mCall)) {
// the above method takes care of Samsung Galaxy S
Toast.makeText(this, R.string.couldnt_accept_call, Toast.LENGTH_LONG).show();
}
}
private void checkAndRequestCallPermissions() {
ArrayList permissionsList = new ArrayList<>();
int recordAudio =
getPackageManager()
.checkPermission(Manifest.permission.RECORD_AUDIO, getPackageName());
Log.i(
"[Permission] Record audio permission is "
+ (recordAudio == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
int camera =
getPackageManager().checkPermission(Manifest.permission.CAMERA, getPackageName());
Log.i(
"[Permission] Camera permission is "
+ (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
int readPhoneState =
getPackageManager()
.checkPermission(Manifest.permission.READ_PHONE_STATE, getPackageName());
Log.i(
"[Permission] Read phone state permission is "
+ (camera == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"));
if (recordAudio != PackageManager.PERMISSION_GRANTED) {
Log.i("[Permission] Asking for record audio");
permissionsList.add(Manifest.permission.RECORD_AUDIO);
}
if (readPhoneState != PackageManager.PERMISSION_GRANTED) {
Log.i("[Permission] Asking for read phone state");
permissionsList.add(Manifest.permission.READ_PHONE_STATE);
}
if (LinphonePreferences.instance().shouldAutomaticallyAcceptVideoRequests()
&& mCall != null
&& mCall.getRemoteParams() != null
&& mCall.getRemoteParams().videoEnabled()) {
if (camera != PackageManager.PERMISSION_GRANTED) {
Log.i("[Permission] Asking for camera");
permissionsList.add(Manifest.permission.CAMERA);
}
}
if (permissionsList.size() > 0) {
String[] permissions = new String[permissionsList.size()];
permissions = permissionsList.toArray(permissions);
ActivityCompat.requestPermissions(this, permissions, 0);
}
}
@Override
public void onRequestPermissionsResult(
int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; i++) {
Log.i(
"[Permission] "
+ permissions[i]
+ " is "
+ (grantResults[i] == PackageManager.PERMISSION_GRANTED
? "granted"
: "denied"));
if (permissions[i].equals(Manifest.permission.CAMERA)
&& grantResults[i] == PackageManager.PERMISSION_GRANTED) {
LinphoneUtils.reloadVideoDevices();
}
}
}
}