notifications: change ringID to username

If a username is registered, this username is displayed in
notifications (incoming texts and calls) instead of the ringID.

Change-Id: I7e4329f1fc13a36911d9ffe8a7f02c95c3d16c36
Tuleap: #1345
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
index 5365e17..839fd37 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/CallFragment.java
@@ -78,6 +78,7 @@
 import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
 import cx.ring.interfaces.CallInterface;
+import cx.ring.interfaces.NameLookupCallback;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
 import cx.ring.model.SecureSipCall;
@@ -94,7 +95,7 @@
 import ezvcard.VCard;
 import ezvcard.property.Photo;
 
-public class CallFragment extends Fragment implements CallInterface, ContactDetailsTask.DetailsLoadedCallback, LocalService.NameLookupCallback {
+public class CallFragment extends Fragment implements CallInterface, ContactDetailsTask.DetailsLoadedCallback, NameLookupCallback {
 
     static final private String TAG = CallFragment.class.getSimpleName();
 
diff --git a/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
index 529b378..873ab11 100644
--- a/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
+++ b/ring-android/app/src/main/java/cx/ring/fragments/SmartListFragment.java
@@ -74,6 +74,7 @@
 import cx.ring.client.ConversationActivity;
 import cx.ring.client.HomeActivity;
 import cx.ring.client.QRCodeScannerActivity;
+import cx.ring.interfaces.NameLookupCallback;
 import cx.ring.model.Account;
 import cx.ring.model.CallContact;
 import cx.ring.model.Conference;
@@ -93,7 +94,7 @@
         SmartListAdapter.SmartListAdapterCallback,
         Conversation.ConversationActionCallback,
         ClipboardHelper.ClipboardHelperCallback,
-        LocalService.NameLookupCallback {
+        NameLookupCallback {
     private static final String TAG = SmartListFragment.class.getSimpleName();
 
     private static final int USER_INPUT_DELAY = 300;
@@ -153,7 +154,7 @@
     public static final int REQUEST_TRANSFER = 10;
     public static final int REQUEST_CONF = 20;
 
-    private LocalService.NameLookupCallback mRinguifyCallback = new LocalService.NameLookupCallback() {
+    private NameLookupCallback mRinguifyCallback = new NameLookupCallback() {
 
         private void updateContactRingId(String name, String address) {
 
diff --git a/ring-android/app/src/main/java/cx/ring/interfaces/NameLookupCallback.java b/ring-android/app/src/main/java/cx/ring/interfaces/NameLookupCallback.java
new file mode 100644
index 0000000..7ca5957
--- /dev/null
+++ b/ring-android/app/src/main/java/cx/ring/interfaces/NameLookupCallback.java
@@ -0,0 +1,28 @@
+/*
+ *  Copyright (C) 2016 Savoir-faire Linux Inc.
+ *
+ *  Author: Aline Bonnet <aline.bonnet@savoirfairelinux.com>
+ *
+ *  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 <http://www.gnu.org/licenses/>.
+ */
+
+package cx.ring.interfaces;
+
+public interface NameLookupCallback {
+    void onFound(String name, String address);
+
+    void onInvalidName(String name);
+
+    void onError(String name, String address);
+}
diff --git a/ring-android/app/src/main/java/cx/ring/service/LocalService.java b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
index bca8b91..9731c54 100644
--- a/ring-android/app/src/main/java/cx/ring/service/LocalService.java
+++ b/ring-android/app/src/main/java/cx/ring/service/LocalService.java
@@ -42,6 +42,7 @@
 import android.net.NetworkInfo;
 import android.os.AsyncTask;
 import android.os.Binder;
+import android.os.Bundle;
 import android.os.IBinder;
 import android.os.RemoteException;
 import android.preference.PreferenceManager;
@@ -82,6 +83,7 @@
 import cx.ring.R;
 import cx.ring.application.RingApplication;
 import cx.ring.client.ConversationActivity;
+import cx.ring.interfaces.NameLookupCallback;
 import cx.ring.loaders.AccountsLoader;
 import cx.ring.loaders.ContactsLoader;
 import cx.ring.model.Account;
@@ -106,7 +108,7 @@
 import cx.ring.utils.MediaManager;
 import cx.ring.utils.Tuple;
 
-public class LocalService extends Service implements Observer {
+public class LocalService extends Service implements Observer, NameLookupCallback {
     static final String TAG = LocalService.class.getSimpleName();
 
     // Emitting events
@@ -165,16 +167,8 @@
 
     private boolean mAreConversationsLoaded = false;
     private NotificationCompat.Builder mMessageNotificationBuilder;
+    private int mNotificationID;
 
-    public interface NameLookupCallback {
-        void onFound(String name, String address);
-
-        void onInvalidName(String name);
-
-        void onError(String name, String address);
-    }
-
-    ;
     final private Map<String, ArrayList<NameLookupCallback>> currentNameLookup = new HashMap<>();
     final private Map<String, ArrayList<NameLookupCallback>> currentAddressLookup = new HashMap<>();
 
@@ -1325,6 +1319,10 @@
                         .setDefaults(NotificationCompat.DEFAULT_ALL)
                         .setSmallIcon(R.drawable.ic_ring_logo_white)
                         .setContentTitle(contact.getDisplayName());
+                String[] split = contact.getDisplayName().split(":");
+                if (split.length > 0) {
+                    lookupAddress("", split[1], this);
+                }
             }
             Intent c_intent = new Intent(Intent.ACTION_VIEW)
                     .setClass(this, ConversationActivity.class)
@@ -1361,7 +1359,8 @@
                 mMessageNotificationBuilder.setStyle(inboxStyle);
                 mMessageNotificationBuilder.setWhen(texts.lastEntry().getValue().getTimestamp());
             }
-            notificationManager.notify(c.getUuid(), mMessageNotificationBuilder.build());
+            mNotificationID = c.getUuid();
+            notificationManager.notify(mNotificationID, mMessageNotificationBuilder.build());
         }
     }
 
@@ -1647,7 +1646,15 @@
                     }
 
                     conversation.addConference(toAdd);
-                    ActionHelper.showCallNotification(LocalService.this, toAdd);
+                    Pair<NotificationCompat.Builder, Integer> notificationResult = ActionHelper.showCallNotification(LocalService.this, toAdd);
+                    mMessageNotificationBuilder = notificationResult.first;
+                    mNotificationID = notificationResult.second;
+
+                    String[] split = contact.getDisplayName().split(":");
+                    if (split.length > 0) {
+                        lookupAddress("", split[1], LocalService.this);
+                    }
+
                     updateAudioState();
 
                     try {
@@ -1827,4 +1834,31 @@
             updateConnectivityState();
         }
     }
+
+    @Override
+    public void onFound(String name, String address) {
+        if (mMessageNotificationBuilder != null && mNotificationID != -1) {
+            Bundle extras = mMessageNotificationBuilder.getExtras();
+            if (extras != null) {
+                if (extras.getBoolean(CallManagerCallBack.INCOMING_CALL, false)) {
+                    mMessageNotificationBuilder.setContentTitle(getApplicationContext().getString(R.string.notif_incoming_call_title, name));
+                } else {
+                    mMessageNotificationBuilder.setContentTitle(name);
+                }
+            } else {
+                mMessageNotificationBuilder.setContentTitle(name);
+            }
+            notificationManager.notify(mNotificationID, mMessageNotificationBuilder.build());
+        }
+    }
+
+    @Override
+    public void onInvalidName(String name) {
+
+    }
+
+    @Override
+    public void onError(String name, String address) {
+
+    }
 }
diff --git a/ring-android/app/src/main/java/cx/ring/utils/ActionHelper.java b/ring-android/app/src/main/java/cx/ring/utils/ActionHelper.java
index c4d6657..907fb97 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/ActionHelper.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/ActionHelper.java
@@ -26,10 +26,12 @@
 import android.content.Intent;
 import android.content.res.Resources;
 import android.graphics.Bitmap;
+import android.os.Bundle;
 import android.provider.ContactsContract;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.app.NotificationManagerCompat;
 import android.support.v7.app.AlertDialog;
+import android.util.Pair;
 
 import java.util.ArrayList;
 import java.util.Random;
@@ -43,6 +45,7 @@
 import cx.ring.model.Phone;
 import cx.ring.model.SipCall;
 import cx.ring.model.Uri;
+import cx.ring.service.CallManagerCallBack;
 import cx.ring.service.LocalService;
 
 public class ActionHelper {
@@ -203,13 +206,14 @@
         }
     }
 
-    public static void showCallNotification(Context ctx, Conference conference) {
+    public static Pair<NotificationCompat.Builder, Integer> showCallNotification(Context ctx, Conference conference) {
         NotificationManagerCompat notificationManager = NotificationManagerCompat.from(ctx);
         notificationManager.cancel(conference.getUuid());
 
         if (conference.getParticipants().isEmpty()) {
-            return;
+            return new Pair<>(null, -1);
         }
+
         SipCall call = conference.getParticipants().get(0);
         CallContact contact = call.getContact();
         final android.net.Uri callUri = android.net.Uri.withAppendedPath(ContentUriHandler.CALL_CONTENT_URI, call.getCallId());
@@ -229,6 +233,8 @@
                                     PendingIntent.FLAG_ONE_SHOT));
         } else if (conference.isRinging()) {
             if (conference.isIncoming()) {
+                Bundle extras = new Bundle();
+                extras.putBoolean(CallManagerCallBack.INCOMING_CALL, true);
                 notificationBuilder.setContentTitle(ctx.getString(R.string.notif_incoming_call_title, contact.getDisplayName()))
                         .setPriority(NotificationCompat.PRIORITY_MAX)
                         .setContentText(ctx.getText(R.string.notif_incoming_call))
@@ -245,7 +251,8 @@
                                         new Intent(LocalService.ACTION_CALL_REFUSE)
                                                 .setClass(ctx, LocalService.class)
                                                 .setData(callUri),
-                                        PendingIntent.FLAG_ONE_SHOT));
+                                        PendingIntent.FLAG_ONE_SHOT))
+                .addExtras(extras);
             } else {
                 notificationBuilder.setContentTitle(ctx.getString(R.string.notif_outgoing_call_title, contact.getDisplayName()))
                         .setContentText(ctx.getText(R.string.notif_outgoing_call))
@@ -260,7 +267,7 @@
 
         } else {
             notificationManager.cancel(conference.getUuid());
-            return;
+            return new Pair<>(null, -1);
         }
 
         notificationBuilder.setOngoing(true).setCategory(NotificationCompat.CATEGORY_CALL).setSmallIcon(R.drawable.ic_ring_logo_white);
@@ -274,7 +281,11 @@
                 notificationBuilder.setLargeIcon(Bitmap.createScaledBitmap(bmp, width, height, false));
             }
         }
-        notificationManager.notify(conference.getUuid(), notificationBuilder.build());
+
+        int notificationId = conference.getUuid();
+        notificationManager.notify(notificationId, notificationBuilder.build());
+
+        return new Pair<>(notificationBuilder, notificationId);
     }
 
     public static Intent getViewIntent(Context context, Conference conference) {
diff --git a/ring-android/app/src/main/java/cx/ring/utils/BlockchainInputHandler.java b/ring-android/app/src/main/java/cx/ring/utils/BlockchainInputHandler.java
index 11c827b..1621a10 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/BlockchainInputHandler.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/BlockchainInputHandler.java
@@ -23,6 +23,7 @@
 
 import java.lang.ref.WeakReference;
 
+import cx.ring.interfaces.NameLookupCallback;
 import cx.ring.service.LocalService;
 
 public class BlockchainInputHandler extends Thread {
@@ -30,17 +31,17 @@
     private static final String TAG = BlockchainInputHandler.class.getName();
 
     private static final String RINGID_PATTERN = "^[a-f0-9]{40}$";
-    private static final int WAIT_DELAY= 2000;
+    private static final int WAIT_DELAY = 2000;
     private static final int KILL_DELAY = 6000;
 
     private WeakReference<LocalService> mLocalService;
     private String mTextToLookup;
-    private LocalService.NameLookupCallback mLookupCallback;
+    private NameLookupCallback mLookupCallback;
 
     private boolean mIsWaitingForInputs = false;
     private long mLastEnqueuedInputTimeStamp = -1;
 
-    public BlockchainInputHandler(@NonNull WeakReference<LocalService> localService, @NonNull LocalService.NameLookupCallback lookupCallback) {
+    public BlockchainInputHandler(@NonNull WeakReference<LocalService> localService, @NonNull NameLookupCallback lookupCallback) {
         mLocalService = localService;
         mLookupCallback = lookupCallback;
     }
diff --git a/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java b/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java
index 6ac79e0..1d98d0f 100644
--- a/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java
+++ b/ring-android/app/src/main/java/cx/ring/utils/BlockchainTextWatcher.java
@@ -28,9 +28,10 @@
 import java.lang.ref.WeakReference;
 
 import cx.ring.R;
+import cx.ring.interfaces.NameLookupCallback;
 import cx.ring.service.LocalService;
 
-public class BlockchainTextWatcher implements TextWatcher, LocalService.NameLookupCallback {
+public class BlockchainTextWatcher implements TextWatcher, NameLookupCallback {
 
     private static final String TAG = BlockchainTextWatcher.class.getName();