linphone-android/app/src/main/java/org/linphone/LinphoneContext.java
2019-09-18 10:05:32 +02:00

282 lines
10 KiB
Java

package org.linphone;
/*
LinphoneContext.java
Copyright (C) 2019 Belledonne Communications, Grenoble, France
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 2
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Build;
import android.os.Handler;
import android.provider.ContactsContract;
import org.linphone.call.CallActivity;
import org.linphone.call.CallIncomingActivity;
import org.linphone.call.CallOutgoingActivity;
import org.linphone.compatibility.Compatibility;
import org.linphone.contacts.ContactsManager;
import org.linphone.core.Call;
import org.linphone.core.Core;
import org.linphone.core.CoreListenerStub;
import org.linphone.core.Factory;
import org.linphone.core.LogLevel;
import org.linphone.core.LoggingService;
import org.linphone.core.LoggingServiceListener;
import org.linphone.core.tools.Log;
import org.linphone.mediastream.Version;
import org.linphone.notifications.NotificationsManager;
import org.linphone.settings.LinphonePreferences;
import org.linphone.utils.LinphoneUtils;
public class LinphoneContext {
private static LinphoneContext sInstance = null;
private Context mContext;
public final Handler handler = new Handler();
private final LoggingServiceListener mJavaLoggingService =
new LoggingServiceListener() {
@Override
public void onLogMessageWritten(
LoggingService logService, String domain, LogLevel lev, String message) {
switch (lev) {
case Debug:
android.util.Log.d(domain, message);
break;
case Message:
android.util.Log.i(domain, message);
break;
case Warning:
android.util.Log.w(domain, message);
break;
case Error:
android.util.Log.e(domain, message);
break;
case Fatal:
default:
android.util.Log.wtf(domain, message);
break;
}
}
};
private CoreListenerStub mListener;
private NotificationsManager mNotificationManager;
private LinphoneManager mLinphoneManager;
private ContactsManager mContactsManager;
private Class<? extends Activity> mIncomingReceivedActivity = CallIncomingActivity.class;
public static boolean isReady() {
return sInstance != null;
}
public static LinphoneContext instance() {
return sInstance;
}
public LinphoneContext(Context context) {
mContext = context;
LinphonePreferences.instance().setContext(context);
Factory.instance().setLogCollectionPath(context.getFilesDir().getAbsolutePath());
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
LinphoneUtils.configureLoggingService(isDebugEnabled, context.getString(R.string.app_name));
// Dump some debugging information to the logs
dumpDeviceInformation();
dumpLinphoneInformation();
String incomingReceivedActivityName =
LinphonePreferences.instance().getActivityToLaunchOnIncomingReceived();
try {
mIncomingReceivedActivity =
(Class<? extends Activity>) Class.forName(incomingReceivedActivityName);
} catch (ClassNotFoundException e) {
Log.e(e);
}
sInstance = this;
Log.i("[Context] Ready");
mListener =
new CoreListenerStub() {
@Override
public void onCallStateChanged(
Core core, Call call, Call.State state, String message) {
if (mContext.getResources().getBoolean(R.bool.enable_call_notification)) {
mNotificationManager.displayCallNotification(call);
}
if (state == Call.State.IncomingReceived
|| state == Call.State.IncomingEarlyMedia) {
// Starting SDK 24 (Android 7.0) we rely on the fullscreen intent of the
// call incoming notification
if (Version.sdkStrictlyBelow(Version.API24_NOUGAT_70)) {
if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
}
} else if (state == Call.State.OutgoingInit) {
onOutgoingStarted();
} else if (state == Call.State.Connected) {
onCallStarted();
} else if (state == Call.State.End
|| state == Call.State.Released
|| state == Call.State.Error) {
if (LinphoneService.isReady()) {
LinphoneService.instance().destroyOverlay();
}
if (state == Call.State.Released
&& call.getCallLog().getStatus() == Call.Status.Missed) {
mNotificationManager.displayMissedCallNotification(call);
}
}
}
};
mLinphoneManager = new LinphoneManager(context);
mNotificationManager = new NotificationsManager(context);
}
public void start(boolean isPush) {
Log.i("[Context] Starting");
mLinphoneManager.startLibLinphone(isPush);
LinphoneManager.getCore().addListener(mListener);
mNotificationManager.onCoreReady();
mContactsManager = new ContactsManager(mContext, handler);
if (!Version.sdkAboveOrEqual(Version.API26_O_80)
|| (mContactsManager.hasReadContactsAccess())) {
mContext.getContentResolver()
.registerContentObserver(
ContactsContract.Contacts.CONTENT_URI, true, mContactsManager);
}
if (mContactsManager.hasReadContactsAccess()) {
mContactsManager.enableContactsAccess();
}
mContactsManager.initializeContactManager();
}
public void destroy() {
Log.i("[Context] Destroying");
Core core = LinphoneManager.getCore();
if (core != null) {
core.removeListener(mListener);
core = null; // To allow the gc calls below to free the Core
}
// Make sure our notification is gone.
if (mNotificationManager != null) {
mNotificationManager.destroy();
}
if (mContactsManager != null) {
mContactsManager.destroy();
}
// Destroy the LinphoneManager second to last to ensure any getCore() call will work
if (mLinphoneManager != null) {
mLinphoneManager.destroy();
}
// Wait for every other object to be destroyed to make LinphoneService.instance() invalid
sInstance = null;
if (LinphonePreferences.instance().useJavaLogger()) {
Factory.instance().getLoggingService().removeListener(mJavaLoggingService);
}
LinphonePreferences.instance().destroy();
}
public void updateContext(Context context) {
mContext = context;
}
public Context getApplicationContext() {
return mContext;
}
/* Managers accessors */
public LoggingServiceListener getJavaLoggingService() {
return mJavaLoggingService;
}
public NotificationsManager getNotificationManager() {
return mNotificationManager;
}
public LinphoneManager getLinphoneManager() {
return mLinphoneManager;
}
public ContactsManager getContactsManager() {
return mContactsManager;
}
/* Log device related information */
private void dumpDeviceInformation() {
Log.i("==== Phone information dump ====");
Log.i("DISPLAY NAME=" + Compatibility.getDeviceName(mContext));
Log.i("DEVICE=" + Build.DEVICE);
Log.i("MODEL=" + Build.MODEL);
Log.i("MANUFACTURER=" + Build.MANUFACTURER);
Log.i("ANDROID SDK=" + Build.VERSION.SDK_INT);
StringBuilder sb = new StringBuilder();
sb.append("ABIs=");
for (String abi : Version.getCpuAbis()) {
sb.append(abi).append(", ");
}
Log.i(sb.substring(0, sb.length() - 2));
}
private void dumpLinphoneInformation() {
Log.i("==== Linphone information dump ====");
Log.i("VERSION NAME=" + BuildConfig.VERSION_NAME);
Log.i("VERSION CODE=" + BuildConfig.VERSION_CODE);
Log.i("PACKAGE=" + BuildConfig.APPLICATION_ID);
Log.i("BUILD TYPE=" + BuildConfig.BUILD_TYPE);
Log.i("SDK VERSION=" + mContext.getString(R.string.linphone_sdk_version));
Log.i("SDK BRANCH=" + mContext.getString(R.string.linphone_sdk_branch));
}
/* Call activities */
private void onIncomingReceived() {
Intent intent = new Intent().setClass(mContext, mIncomingReceivedActivity);
// This flag is required to start an Activity from a Service context
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
private void onOutgoingStarted() {
Intent intent = new Intent(mContext, CallOutgoingActivity.class);
// This flag is required to start an Activity from a Service context
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
private void onCallStarted() {
Intent intent = new Intent(mContext, CallActivity.class);
// This flag is required to start an Activity from a Service context
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent);
}
}