Show work badge icon/description in InCallUI/Dialer

Add work badge icon into IncallUI
Add work description into incoming call notification

To see this feature
1. Receive/Make a call from work contact
   (a contact in work profile has the phone number)
2. See work description in incoming call notification
   and work badge icon in IncallUI

BUG=26082618

Change-Id: I182b48a34d3d87ee3093e8433ae33939705d59d7
diff --git a/InCallUI/res/layout/primary_call_info.xml b/InCallUI/res/layout/primary_call_info.xml
index 629d220..5dcebd0 100644
--- a/InCallUI/res/layout/primary_call_info.xml
+++ b/InCallUI/res/layout/primary_call_info.xml
@@ -69,6 +69,17 @@
             android:clipChildren="false"
             android:clipToPadding="false">
 
+            <ImageView android:id="@+id/workProfileIcon"
+                android:src="@drawable/ic_work_profile"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_weight="0"
+                android:layout_marginEnd="8dp"
+                android:baselineAlignBottom="true"
+                android:tint="@color/incall_accent_color"
+                android:scaleType="center"
+                android:visibility="gone" />
+
             <!-- Subscription provider or WiFi calling icon displayed to the left of the label -->
             <ImageView android:id="@+id/callStateIcon"
                 android:layout_width="24dp"
diff --git a/InCallUI/res/values/strings.xml b/InCallUI/res/values/strings.xml
index b30ca65..41b2852 100644
--- a/InCallUI/res/values/strings.xml
+++ b/InCallUI/res/values/strings.xml
@@ -145,16 +145,26 @@
     <string name="notification_missedCallTicker">Missed call from <xliff:g id="missed_call_from">%s</xliff:g></string>
     <!-- The "label" of the in-call Notification for an ongoing call. [CHAR LIMIT=60] -->
     <string name="notification_ongoing_call">Ongoing call</string>
+    <!-- The "label" of the in-call Notification for an ongoing work call. [CHAR LIMIT=60] -->
+    <string name="notification_ongoing_work_call">Ongoing work call</string>
     <!-- The "label" of the in-call Notification for an ongoing call, which is being made over
          Wi-Fi. [CHAR LIMIT=60] -->
     <string name="notification_ongoing_call_wifi">Ongoing Wi-Fi call</string>
+    <!-- The "label" of the in-call Notification for an ongoing work call, which is being made
+         over Wi-Fi. [CHAR LIMIT=60] -->
+    <string name="notification_ongoing_work_call_wifi">Ongoing Wi-Fi work call</string>
     <!-- The "label" of the in-call Notification for a call that's on hold -->
     <string name="notification_on_hold">On hold</string>
     <!-- The "label" of the in-call Notification for an incoming ringing call. [CHAR LIMIT=60] -->
     <string name="notification_incoming_call">Incoming call</string>
+    <!-- The "label" of the in-call Notification for an incoming ringing call. [CHAR LIMIT=60] -->
+    <string name="notification_incoming_work_call">Incoming work call</string>
     <!-- The "label" of the in-call Notification for an incoming ringing call,
          which is being made over Wi-Fi. [CHAR LIMIT=60] -->
     <string name="notification_incoming_call_wifi">Incoming Wi-Fi call</string>
+    <!-- The "label" of the in-call Notification for an incoming ringing work call,
+         which is being made over Wi-Fi. [CHAR LIMIT=60] -->
+    <string name="notification_incoming_work_call_wifi">Incoming Wi-Fi work call</string>
     <!-- The "label" of the in-call Notification for an incoming ringing video call. -->
     <string name="notification_incoming_video_call">Incoming video call</string>
     <!-- The "label" of the in-call Notification for upgrading an existing call to a video call. -->
diff --git a/InCallUI/src/com/android/incallui/CallCardFragment.java b/InCallUI/src/com/android/incallui/CallCardFragment.java
index dbb2c9d..93d499e 100644
--- a/InCallUI/src/com/android/incallui/CallCardFragment.java
+++ b/InCallUI/src/com/android/incallui/CallCardFragment.java
@@ -132,6 +132,7 @@
     private TextView mElapsedTime;
     private Drawable mPrimaryPhotoDrawable;
     private TextView mCallSubject;
+    private ImageView mWorkProfileIcon;
 
     // Container view that houses the entire primary call card, including the call buttons
     private View mPrimaryCallCardContainer;
@@ -273,6 +274,7 @@
 
         mCallStateIcon = (ImageView) view.findViewById(R.id.callStateIcon);
         mCallStateVideoCallIcon = (ImageView) view.findViewById(R.id.videoCallIcon);
+        mWorkProfileIcon = (ImageView) view.findViewById(R.id.workProfileIcon);
         mCallStateLabel = (TextView) view.findViewById(R.id.callStateLabel);
         mHdAudioIcon = (ImageView) view.findViewById(R.id.hdAudioIcon);
         mForwardIcon = (ImageView) view.findViewById(R.id.forwardIcon);
@@ -560,7 +562,7 @@
      */
     @Override
     public void setPrimary(String number, String name, boolean nameIsNumber, String label,
-            Drawable photo, boolean isSipCall, boolean isContactPhotoShown) {
+            Drawable photo, boolean isSipCall, boolean isContactPhotoShown, boolean isWorkContact) {
         Log.d(this, "Setting primary call");
         // set the name field.
         setPrimaryName(name, nameIsNumber);
@@ -582,6 +584,7 @@
 
         setDrawableToImageViews(photo);
         showImageView(mPhotoLarge, isContactPhotoShown);
+        showImageView(mWorkProfileIcon, isWorkContact);
     }
 
     @Override
diff --git a/InCallUI/src/com/android/incallui/CallCardPresenter.java b/InCallUI/src/com/android/incallui/CallCardPresenter.java
index 0b17e1a..a52a36d 100644
--- a/InCallUI/src/com/android/incallui/CallCardPresenter.java
+++ b/InCallUI/src/com/android/incallui/CallCardPresenter.java
@@ -39,6 +39,7 @@
 import android.view.accessibility.AccessibilityManager;
 import android.widget.ListAdapter;
 
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.compat.telecom.TelecomManagerCompat;
 import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.util.ContactDisplayUtils;
@@ -712,7 +713,7 @@
 
         if (mPrimary == null) {
             // Clear the primary display info.
-            ui.setPrimary(null, null, false, null, null, false, false);
+            ui.setPrimary(null, null, false, null, null, false, false, false);
             return;
         }
 
@@ -731,7 +732,8 @@
                     null /* label */,
                     getConferencePhoto(mPrimary),
                     false /* isSipCall */,
-                    showContactPhoto);
+                    showContactPhoto,
+                    false /* isWorkContact */);
         } else if (mPrimaryContactInfo != null) {
             Log.d(TAG, "Update primary display info for " + mPrimaryContactInfo);
 
@@ -763,6 +765,7 @@
             maybeShowHdAudioIcon();
 
             boolean nameIsNumber = name != null && name.equals(mPrimaryContactInfo.number);
+            boolean isWorkContact = (mPrimaryContactInfo.userType == ContactsUtils.USER_TYPE_WORK);
             ui.setPrimary(
                     number,
                     name,
@@ -770,12 +773,13 @@
                     isChildNumberShown || isCallSubjectShown ? null : mPrimaryContactInfo.label,
                     mPrimaryContactInfo.photo,
                     mPrimaryContactInfo.isSipCall,
-                    showContactPhoto);
+                    showContactPhoto,
+                    isWorkContact);
 
             updateContactInteractions();
         } else {
             // Clear the primary display info.
-            ui.setPrimary(null, null, false, null, null, false, false);
+            ui.setPrimary(null, null, false, null, null, false, false, false);
         }
 
         if (mEmergencyCallListener != null) {
@@ -1091,7 +1095,8 @@
         void showContactContext(boolean show);
         void setCallCardVisible(boolean visible);
         void setPrimary(String number, String name, boolean nameIsNumber, String label,
-                Drawable photo, boolean isSipCall, boolean isContactPhotoShown);
+                Drawable photo, boolean isSipCall, boolean isContactPhotoShown,
+                boolean isWorkContact);
         void setSecondary(boolean show, String name, boolean nameIsNumber, String label,
                 String providerLabel, boolean isConference, boolean isVideoCall,
                 boolean isFullscreen);
diff --git a/InCallUI/src/com/android/incallui/CallerInfo.java b/InCallUI/src/com/android/incallui/CallerInfo.java
index 4ea4970..6096961 100644
--- a/InCallUI/src/com/android/incallui/CallerInfo.java
+++ b/InCallUI/src/com/android/incallui/CallerInfo.java
@@ -16,12 +16,15 @@
 
 package com.android.incallui;
 
+import com.google.common.primitives.Longs;
+
 import android.content.Context;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.drawable.Drawable;
 import android.net.Uri;
 import android.provider.ContactsContract.CommonDataKinds.Phone;
+import android.provider.ContactsContract;
 import android.provider.ContactsContract.Contacts;
 import android.provider.ContactsContract.Data;
 import android.provider.ContactsContract.PhoneLookup;
@@ -29,6 +32,8 @@
 import android.telephony.PhoneNumberUtils;
 import android.text.TextUtils;
 
+import com.android.contacts.common.ContactsUtils;
+import com.android.contacts.common.ContactsUtils.UserType;
 import com.android.contacts.common.util.PhoneNumberHelper;
 import com.android.contacts.common.util.TelephonyManagerUtils;
 import com.android.dialer.calllog.ContactInfoHelper;
@@ -103,6 +108,7 @@
     public String lookupKeyOrNull;
     public boolean needUpdate;
     public Uri contactRefUri;
+    public @UserType long userType;
 
     /**
      * Contact display photo URI.  If a contact has no display photo but a thumbnail, it'll be
@@ -161,6 +167,7 @@
         // TODO: Move all the basic initialization here?
         mIsEmergency = false;
         mIsVoiceMail = false;
+        userType = ContactsUtils.USER_TYPE_CURRENT;
     }
 
     /**
@@ -180,6 +187,7 @@
         info.cachedPhoto = null;
         info.isCachedPhotoCurrent = false;
         info.contactExists = false;
+        info.userType = ContactsUtils.USER_TYPE_CURRENT;
 
         Log.v(TAG, "getCallerInfo() based on cursor...");
 
@@ -189,6 +197,7 @@
                 // care of here. Maybe we should store it in the
                 // CallerInfo object as well.
 
+                long contactId = 0L;
                 int columnIndex;
 
                 // Look for the name
@@ -231,7 +240,7 @@
                 // Look for the person_id.
                 columnIndex = getColumnIndexForPersonId(contactRef, cursor);
                 if (columnIndex != -1) {
-                    final long contactId = cursor.getLong(columnIndex);
+                    contactId = cursor.getLong(columnIndex);
                     if (contactId != 0 && !Contacts.isEnterpriseContactId(contactId)) {
                         info.contactIdOrZero = contactId;
                         Log.v(TAG, "==> got info.contactIdOrZero: " + info.contactIdOrZero);
@@ -278,6 +287,12 @@
                 info.shouldSendToVoicemail = (columnIndex != -1) &&
                         ((cursor.getInt(columnIndex)) == 1);
                 info.contactExists = true;
+
+                // Determine userType by directoryId and contactId
+                final String directory = contactRef == null ? null
+                        : contactRef.getQueryParameter(ContactsContract.DIRECTORY_PARAM_KEY);
+                final Long directoryId = directory == null ? null : Longs.tryParse(directory);
+                info.userType = ContactsUtils.determineUserType(directoryId, contactId);
             }
             cursor.close();
         }
@@ -524,7 +539,8 @@
                     .append("\ncachedPhoto: " + cachedPhoto)
                     .append("\nisCachedPhotoCurrent: " + isCachedPhotoCurrent)
                     .append("\nemergency: " + mIsEmergency)
-                    .append("\nvoicemail " + mIsVoiceMail)
+                    .append("\nvoicemail: " + mIsVoiceMail)
+                    .append("\nuserType: " + userType)
                     .append(" }")
                     .toString();
         } else {
diff --git a/InCallUI/src/com/android/incallui/CallerInfoUtils.java b/InCallUI/src/com/android/incallui/CallerInfoUtils.java
index 31fc9f1..ae59d7d 100644
--- a/InCallUI/src/com/android/incallui/CallerInfoUtils.java
+++ b/InCallUI/src/com/android/incallui/CallerInfoUtils.java
@@ -109,6 +109,7 @@
         info.number = ci.phoneNumber;
         info.normalizedNumber = ci.normalizedNumber;
         info.photoUri = ci.contactDisplayPhotoUri;
+        info.userType = ci.userType;
 
         CachedContactInfo cacheInfo = lookupService.buildCachedContactInfo(info);
         cacheInfo.setLookupKey(ci.lookupKeyOrNull);
diff --git a/InCallUI/src/com/android/incallui/ContactInfoCache.java b/InCallUI/src/com/android/incallui/ContactInfoCache.java
index 9894f55..bba973b 100644
--- a/InCallUI/src/com/android/incallui/ContactInfoCache.java
+++ b/InCallUI/src/com/android/incallui/ContactInfoCache.java
@@ -37,6 +37,7 @@
 import android.text.TextUtils;
 import android.util.Pair;
 
+import com.android.contacts.common.ContactsUtils;
 import com.android.contacts.common.util.PhoneNumberHelper;
 import com.android.dialer.calllog.ContactInfo;
 import com.android.dialer.service.CachedNumberLookupService;
@@ -553,6 +554,7 @@
         cce.location = displayLocation;
         cce.label = label;
         cce.isSipCall = isSipCall;
+        cce.userType = info.userType;
 
         if (info.contactExists) {
             cce.contactLookupResult = LogState.LOOKUP_LOCAL_CONTACT;
@@ -660,6 +662,7 @@
         public Address locationAddress;
         public List<Pair<Calendar, Calendar>> openingHours;
         public int contactLookupResult = LogState.LOOKUP_NOT_FOUND;
+        public long userType = ContactsUtils.USER_TYPE_CURRENT;
 
         @Override
         public String toString() {
@@ -676,6 +679,7 @@
                     .add("locationAddress", locationAddress)
                     .add("openingHours", openingHours)
                     .add("contactLookupResult", contactLookupResult)
+                    .add("userType", userType)
                     .toString();
         }
     }
diff --git a/InCallUI/src/com/android/incallui/StatusBarNotifier.java b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
index 1f2729e..fdf185b 100644
--- a/InCallUI/src/com/android/incallui/StatusBarNotifier.java
+++ b/InCallUI/src/com/android/incallui/StatusBarNotifier.java
@@ -34,6 +34,8 @@
 import android.text.TextDirectionHeuristics;
 import android.text.TextUtils;
 
+import com.android.contacts.common.ContactsUtils;
+import com.android.contacts.common.ContactsUtils.UserType;
 import com.android.contacts.common.preference.ContactsPreferences;
 import com.android.contacts.common.util.BitmapUtil;
 import com.android.contacts.common.util.ContactDisplayUtils;
@@ -221,7 +223,8 @@
         // Check if data has changed; if nothing is different, don't issue another notification.
         final int iconResId = getIconToDisplay(call);
         Bitmap largeIcon = getLargeIconToDisplay(contactInfo, call);
-        final String content = getContentString(call);
+        final String content =
+                getContentString(call, contactInfo.userType);
         final String contentTitle = getContentTitle(contactInfo, call);
 
         final int notificationType;
@@ -435,7 +438,7 @@
     /**
      * Returns the message to use with the notification.
      */
-    private String getContentString(Call call) {
+    private String getContentString(Call call, @UserType long userType) {
         boolean isIncomingOrWaiting = call.getState() == Call.State.INCOMING ||
                 call.getState() == Call.State.CALL_WAITING;
 
@@ -469,9 +472,28 @@
             resId = R.string.notification_requesting_video_call;
         }
 
+        if (userType == ContactsUtils.USER_TYPE_WORK) {
+            resId = getWorkStringFromPersonalString(resId);
+        }
+
         return mContext.getString(resId);
     }
 
+    private static int getWorkStringFromPersonalString(int resId) {
+        switch(resId) {
+            case R.string.notification_ongoing_call:
+                return R.string.notification_ongoing_work_call;
+            case R.string.notification_ongoing_call_wifi:
+                return R.string.notification_ongoing_work_call_wifi;
+            case R.string.notification_incoming_call_wifi:
+                return R.string.notification_incoming_work_call_wifi;
+            case R.string.notification_incoming_call:
+                return R.string.notification_incoming_work_call;
+            default:
+                return resId;
+        }
+    }
+
     /**
      * Gets the most relevant call to display in the notification.
      */