Fixed empty history & missing contacts when fetched through remote provisionning
This commit is contained in:
parent
cdf8b55d06
commit
ba6a3c70bb
5 changed files with 144 additions and 97 deletions
|
@ -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<? extends Activity> mIncomingReceivedActivity = CallIncomingActivity.class;
|
||||
private final ArrayList<CoreStartedListener> 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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -79,21 +79,6 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
protected AsyncContactsData doInBackground(Void... params) {
|
||||
Log.i("[Contacts Manager] Background synchronization started");
|
||||
|
||||
String selection = null;
|
||||
if (mContext.getResources().getBoolean(R.bool.fetch_contacts_from_default_directory)) {
|
||||
Log.i("[Contacts Manager] Only fetching contacts in default directory");
|
||||
selection = ContactsContract.Data.IN_DEFAULT_DIRECTORY + " == 1";
|
||||
}
|
||||
|
||||
Cursor c =
|
||||
mContext.getContentResolver()
|
||||
.query(
|
||||
ContactsContract.Data.CONTENT_URI,
|
||||
PROJECTION,
|
||||
selection,
|
||||
null,
|
||||
null);
|
||||
|
||||
HashMap<String, LinphoneContact> androidContactsCache = new HashMap<>();
|
||||
AsyncContactsData data = new AsyncContactsData();
|
||||
List<String> nativeIds = new ArrayList<>();
|
||||
|
@ -110,9 +95,12 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
}
|
||||
|
||||
LinphoneContact contact = (LinphoneContact) friend.getUserData();
|
||||
// A previously fetched friend from rc file will have a user data,
|
||||
// so the next fetches won't add it in data.contacts
|
||||
// and thus the "new friends" count in log will be different /!\
|
||||
if (contact != null) {
|
||||
contact.clearAddresses();
|
||||
if (contact.getAndroidId() != null) {
|
||||
contact.clearAddresses();
|
||||
androidContactsCache.put(contact.getAndroidId(), contact);
|
||||
nativeIds.add(contact.getAndroidId());
|
||||
}
|
||||
|
@ -134,6 +122,21 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
}
|
||||
}
|
||||
|
||||
if (ContactsManager.getInstance().hasReadContactsAccess()) {
|
||||
String selection = null;
|
||||
if (mContext.getResources().getBoolean(R.bool.fetch_contacts_from_default_directory)) {
|
||||
Log.i("[Contacts Manager] Only fetching contacts in default directory");
|
||||
selection = ContactsContract.Data.IN_DEFAULT_DIRECTORY + " == 1";
|
||||
}
|
||||
|
||||
Cursor c =
|
||||
mContext.getContentResolver()
|
||||
.query(
|
||||
ContactsContract.Data.CONTENT_URI,
|
||||
PROJECTION,
|
||||
selection,
|
||||
null,
|
||||
null);
|
||||
if (c != null) {
|
||||
Log.i("[Contacts Manager] Found " + c.getCount() + " entries in cursor");
|
||||
while (c.moveToNext()) {
|
||||
|
@ -163,6 +166,7 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
contact.syncValuesFromAndroidCusor(c);
|
||||
}
|
||||
c.close();
|
||||
}
|
||||
|
||||
FriendList[] friendLists = core.getFriendsLists();
|
||||
for (FriendList list : friendLists) {
|
||||
|
@ -188,7 +192,13 @@ class AsyncContactsLoader extends AsyncTask<Void, Void, AsyncContactsLoader.Asyn
|
|||
}
|
||||
|
||||
Collection<LinphoneContact> 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");
|
||||
|
|
|
@ -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<LinphoneContact> mContacts, mSipContacts;
|
||||
private final ArrayList<ContactsUpdatedListener> 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<LinphoneContact> 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() {
|
||||
|
|
|
@ -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<CallLog> missedCalls = new ArrayList<>();
|
||||
|
|
Loading…
Reference in a new issue