From ba6a3c70bba5dc84331c5ffaec033fe57f802220 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Nov 2019 11:18:15 +0100 Subject: [PATCH] Fixed empty history & missing contacts when fetched through remote provisionning --- .../java/org/linphone/LinphoneContext.java | 47 +++++++- .../java/org/linphone/LinphoneManager.java | 41 ++----- .../contacts/AsyncContactsLoader.java | 100 ++++++++++-------- .../linphone/contacts/ContactsManager.java | 23 ++-- .../org/linphone/history/HistoryFragment.java | 30 ++++-- 5 files changed, 144 insertions(+), 97 deletions(-) diff --git a/app/src/main/java/org/linphone/LinphoneContext.java b/app/src/main/java/org/linphone/LinphoneContext.java index 0db32d971..c02c81a4d 100644 --- a/app/src/main/java/org/linphone/LinphoneContext.java +++ b/app/src/main/java/org/linphone/LinphoneContext.java @@ -26,15 +26,18 @@ import android.content.Context; import android.content.Intent; import android.os.Build; import android.provider.ContactsContract; +import java.util.ArrayList; 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.ConfiguringState; import org.linphone.core.Core; import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; +import org.linphone.core.GlobalState; import org.linphone.core.LogLevel; import org.linphone.core.LoggingService; import org.linphone.core.LoggingServiceListener; @@ -79,6 +82,7 @@ public class LinphoneContext { private LinphoneManager mLinphoneManager; private ContactsManager mContactsManager; private Class mIncomingReceivedActivity = CallIncomingActivity.class; + private final ArrayList mCoreStartedListeners; public static boolean isReady() { return sInstance != null; @@ -90,6 +94,7 @@ public class LinphoneContext { public LinphoneContext(Context context) { mContext = context; + mCoreStartedListeners = new ArrayList<>(); LinphonePreferences.instance().setContext(context); Factory.instance().setLogCollectionPath(context.getFilesDir().getAbsolutePath()); @@ -114,9 +119,35 @@ public class LinphoneContext { mListener = new CoreListenerStub() { + @Override + public void onGlobalStateChanged(Core core, GlobalState state, String message) { + Log.i("[Context] Global state is [", state, "]"); + + if (state == GlobalState.On) { + for (CoreStartedListener listener : mCoreStartedListeners) { + listener.onCoreStarted(); + } + } + } + + @Override + public void onConfiguringStatus( + Core core, ConfiguringState status, String message) { + Log.i("[Context] Configuring state is [", status, "]"); + + if (status == ConfiguringState.Successful) { + LinphonePreferences.instance() + .setPushNotificationEnabled( + LinphonePreferences.instance() + .isPushNotificationEnabled()); + } + } + @Override public void onCallStateChanged( Core core, Call call, Call.State state, String message) { + Log.i("[Context] Call state is [", state, "]"); + if (mContext.getResources().getBoolean(R.bool.enable_call_notification)) { mNotificationManager.displayCallNotification(call); } @@ -161,8 +192,7 @@ public class LinphoneContext { public void start(boolean isPush) { Log.i("[Context] Starting"); - mLinphoneManager.startLibLinphone(isPush); - LinphoneManager.getCore().addListener(mListener); + mLinphoneManager.startLibLinphone(isPush, mListener); mNotificationManager.onCoreReady(); @@ -176,6 +206,7 @@ public class LinphoneContext { if (mContactsManager.hasReadContactsAccess()) { mContactsManager.enableContactsAccess(); } + mContactsManager.initializeContactManager(); } @@ -236,6 +267,14 @@ public class LinphoneContext { return mContactsManager; } + public void addCoreStartedListener(CoreStartedListener listener) { + mCoreStartedListeners.add(listener); + } + + public void removeCoreStartedListener(CoreStartedListener listener) { + mCoreStartedListeners.remove(listener); + } + /* Log device related information */ private void dumpDeviceInformation() { @@ -285,4 +324,8 @@ public class LinphoneContext { intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mContext.startActivity(intent); } + + public interface CoreStartedListener { + void onCoreStarted(); + } } diff --git a/app/src/main/java/org/linphone/LinphoneManager.java b/app/src/main/java/org/linphone/LinphoneManager.java index ea6e900df..fcbc0c57e 100644 --- a/app/src/main/java/org/linphone/LinphoneManager.java +++ b/app/src/main/java/org/linphone/LinphoneManager.java @@ -51,12 +51,11 @@ import org.linphone.core.AccountCreator; import org.linphone.core.AccountCreatorListenerStub; import org.linphone.core.Call; import org.linphone.core.Call.State; -import org.linphone.core.ConfiguringState; import org.linphone.core.Core; +import org.linphone.core.CoreListener; import org.linphone.core.CoreListenerStub; import org.linphone.core.Factory; import org.linphone.core.FriendList; -import org.linphone.core.GlobalState; import org.linphone.core.PresenceActivity; import org.linphone.core.PresenceBasicStatus; import org.linphone.core.PresenceModel; @@ -160,37 +159,6 @@ public class LinphoneManager implements SensorEventListener { mCoreListener = new CoreListenerStub() { - @Override - public void onGlobalStateChanged( - final Core core, final GlobalState state, final String message) { - Log.i("New global state [", state, "]"); - if (state == GlobalState.On) { - try { - initLiblinphone(core); - } catch (IllegalArgumentException iae) { - Log.e( - "[Manager] Global State Changed Illegal Argument Exception: " - + iae); - } - } - } - - @Override - public void onConfiguringStatus( - Core core, ConfiguringState state, String message) { - Log.d( - "[Manager] Remote provisioning status = " - + state.toString() - + " (" - + message - + ")"); - - LinphonePreferences prefs = LinphonePreferences.instance(); - if (state == ConfiguringState.Successful) { - prefs.setPushNotificationEnabled(prefs.isPushNotificationEnabled()); - } - } - @SuppressLint("Wakelock") @Override public void onCallStateChanged( @@ -198,7 +166,7 @@ public class LinphoneManager implements SensorEventListener { final Call call, final State state, final String message) { - Log.i("[Manager] New call state [", state, "]"); + Log.i("[Manager] Call state is [", state, "]"); if (state == State.IncomingReceived && !call.equals(core.getCurrentCall())) { if (call.getReplacedCall() != null) { @@ -429,7 +397,7 @@ public class LinphoneManager implements SensorEventListener { } } - public synchronized void startLibLinphone(boolean isPush) { + public synchronized void startLibLinphone(boolean isPush, CoreListener listener) { try { mCore = Factory.instance() @@ -437,6 +405,7 @@ public class LinphoneManager implements SensorEventListener { mPrefs.getLinphoneDefaultConfig(), mPrefs.getLinphoneFactoryConfig(), mContext); + mCore.addListener(listener); mCore.addListener(mCoreListener); if (isPush) { @@ -466,6 +435,8 @@ public class LinphoneManager implements SensorEventListener { /*use schedule instead of scheduleAtFixedRate to avoid iterate from being call in burst after cpu wake up*/ mTimer = new Timer("Linphone scheduler"); mTimer.schedule(lTask, 0, 20); + + initLiblinphone(mCore); } catch (Exception e) { Log.e(e, "[Manager] Cannot start linphone"); } diff --git a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java index fe4bbf37e..8ad05b069 100644 --- a/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java +++ b/app/src/main/java/org/linphone/contacts/AsyncContactsLoader.java @@ -79,21 +79,6 @@ class AsyncContactsLoader extends AsyncTask androidContactsCache = new HashMap<>(); AsyncContactsData data = new AsyncContactsData(); List nativeIds = new ArrayList<>(); @@ -110,9 +95,12 @@ class AsyncContactsLoader extends AsyncTask contacts = androidContactsCache.values(); - Log.i("[Contacts Manager] Found " + contacts.size() + " contacts"); + // New friends count will be 0 after the first contacts fetch + Log.i( + "[Contacts Manager] Found " + + contacts.size() + + " native contacts plus " + + data.contacts.size() + + " new friends in the configuration file"); for (LinphoneContact contact : contacts) { if (isCancelled()) { Log.w("[Contacts Manager] Task cancelled"); diff --git a/app/src/main/java/org/linphone/contacts/ContactsManager.java b/app/src/main/java/org/linphone/contacts/ContactsManager.java index 82f9c890e..b3e18269a 100644 --- a/app/src/main/java/org/linphone/contacts/ContactsManager.java +++ b/app/src/main/java/org/linphone/contacts/ContactsManager.java @@ -55,7 +55,8 @@ import org.linphone.core.ProxyConfig; import org.linphone.core.tools.Log; import org.linphone.settings.LinphonePreferences; -public class ContactsManager extends ContentObserver implements FriendListListener { +public class ContactsManager extends ContentObserver + implements FriendListListener, LinphoneContext.CoreStartedListener { private List mContacts, mSipContacts; private final ArrayList mContactsUpdatedListeners; private MagicSearch mMagicSearch; @@ -79,6 +80,8 @@ public class ContactsManager extends ContentObserver implements FriendListListen mMagicSearch = LinphoneManager.getCore().createMagicSearch(); mMagicSearch.setLimitedSearch(false); // Do not limit the number of results } + + LinphoneContext.instance().addCoreStartedListener(this); } public void addContactsListener(ContactsUpdatedListener listener) { @@ -104,6 +107,13 @@ public class ContactsManager extends ContentObserver implements FriendListListen fetchContactsAsync(); } + @Override + public void onCoreStarted() { + // Core has been started, fetch contacts again in case there are some + // in the configuration file or remote provisioning + fetchContactsAsync(); + } + public synchronized List getContacts() { return mContacts; } @@ -122,6 +132,7 @@ public class ContactsManager extends ContentObserver implements FriendListListen public void destroy() { mContext.getContentResolver().unregisterContentObserver(this); + LinphoneContext.instance().removeCoreStartedListener(this); if (mLoadContactTask != null) { mLoadContactTask.cancel(true); @@ -149,10 +160,12 @@ public class ContactsManager extends ContentObserver implements FriendListListen if (mLoadContactTask != null) { mLoadContactTask.cancel(true); } + if (!hasReadContactsAccess()) { - Log.w("[Contacts Manager] Can't fetch contact without READ permission"); - return; + Log.w( + "[Contacts Manager] Can't fetch native contacts without READ_CONTACTS permission"); } + mLoadContactTask = new AsyncContactsLoader(mContext); mContactsFetchedOnce = true; mLoadContactTask.executeOnExecutor(THREAD_POOL_EXECUTOR); @@ -264,10 +277,6 @@ public class ContactsManager extends ContentObserver implements FriendListListen } } } - - if (mContext != null && getContacts().isEmpty() && hasReadContactsAccess()) { - fetchContactsAsync(); - } } private void makeContactAccountVisible() { diff --git a/app/src/main/java/org/linphone/history/HistoryFragment.java b/app/src/main/java/org/linphone/history/HistoryFragment.java index 6c86c3492..ea73d2054 100644 --- a/app/src/main/java/org/linphone/history/HistoryFragment.java +++ b/app/src/main/java/org/linphone/history/HistoryFragment.java @@ -35,6 +35,7 @@ import androidx.recyclerview.widget.RecyclerView; import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import org.linphone.LinphoneContext; import org.linphone.LinphoneManager; import org.linphone.R; import org.linphone.contacts.ContactsManager; @@ -51,7 +52,8 @@ public class HistoryFragment extends Fragment OnItemClickListener, HistoryViewHolder.ClickListener, ContactsUpdatedListener, - SelectableHelper.DeleteListener { + SelectableHelper.DeleteListener, + LinphoneContext.CoreStartedListener { private RecyclerView mHistoryList; private TextView mNoCallHistory, mNoMissedCallHistory; private ImageView mMissedCalls, mAllCalls; @@ -101,19 +103,16 @@ public class HistoryFragment extends Fragment public void onResume() { super.onResume(); ContactsManager.getInstance().addContactsListener(this); + LinphoneContext.instance().addCoreStartedListener(this); - mLogs = Arrays.asList(LinphoneManager.getCore().getCallLogs()); - hideHistoryListAndDisplayMessageIfEmpty(); - mHistoryAdapter = - new HistoryAdapter((HistoryActivity) getActivity(), mLogs, this, mSelectionHelper); - mHistoryList.setAdapter(mHistoryAdapter); - mSelectionHelper.setAdapter(mHistoryAdapter); - mSelectionHelper.setDialogMessage(R.string.call_log_delete_dialog); + reloadData(); } @Override public void onPause() { ContactsManager.getInstance().removeContactsListener(this); + LinphoneContext.instance().removeCoreStartedListener(this); + super.onPause(); } @@ -125,6 +124,11 @@ public class HistoryFragment extends Fragment } } + @Override + public void onCoreStarted() { + reloadData(); + } + @Override public void onClick(View v) { int id = v.getId(); @@ -218,6 +222,16 @@ public class HistoryFragment extends Fragment } } + private void reloadData() { + mLogs = Arrays.asList(LinphoneManager.getCore().getCallLogs()); + hideHistoryListAndDisplayMessageIfEmpty(); + mHistoryAdapter = + new HistoryAdapter((HistoryActivity) getActivity(), mLogs, this, mSelectionHelper); + mHistoryList.setAdapter(mHistoryAdapter); + mSelectionHelper.setAdapter(mHistoryAdapter); + mSelectionHelper.setDialogMessage(R.string.call_log_delete_dialog); + } + private void removeNotMissedCallsFromLogs() { if (mOnlyDisplayMissedCalls) { List missedCalls = new ArrayList<>();