Merge "Add turn on/off setting for Lychee in Contacts App." into ub-contactsdialer-b-dev
diff --git a/src/com/android/contacts/common/CallUtil.java b/src/com/android/contacts/common/CallUtil.java
index 7640246..88fca92 100644
--- a/src/com/android/contacts/common/CallUtil.java
+++ b/src/com/android/contacts/common/CallUtil.java
@@ -17,6 +17,7 @@
package com.android.contacts.common;
import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.compat.PhoneAccountSdkCompat;
import com.android.contacts.common.util.PermissionsUtil;
import com.android.contacts.common.util.PhoneNumberHelper;
import com.android.phone.common.PhoneConstants;
@@ -151,7 +152,7 @@
int videoCapabilities = VIDEO_CALLING_ENABLED;
if (account.hasCapabilities(
- PhoneAccount.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
+ PhoneAccountSdkCompat.CAPABILITY_VIDEO_CALLING_RELIES_ON_PRESENCE)) {
videoCapabilities |= VIDEO_CALLING_PRESENCE;
}
return videoCapabilities;
diff --git a/src/com/android/contacts/common/ContactsUtils.java b/src/com/android/contacts/common/ContactsUtils.java
index 2ef68d4..c37e8f8 100644
--- a/src/com/android/contacts/common/ContactsUtils.java
+++ b/src/com/android/contacts/common/ContactsUtils.java
@@ -22,6 +22,7 @@
import android.net.Uri;
import android.os.Build;
import android.provider.ContactsContract.CommonDataKinds.Im;
+import android.support.annotation.IntDef;
import android.provider.ContactsContract.DisplayPhoto;
import android.telephony.PhoneNumberUtils;
import android.text.TextUtils;
@@ -30,8 +31,13 @@
import com.android.contacts.common.model.account.AccountWithDataSet;
import com.android.contacts.common.model.dataitem.ImDataItem;
import com.android.contacts.common.testing.NeededForTesting;
+import com.android.contacts.common.compat.ContactsCompat;
+import com.android.contacts.common.compat.DirectoryCompat;
+import com.android.contacts.common.compat.SdkSelectionUtils;
import com.android.contacts.common.model.AccountTypeManager;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.util.List;
public class ContactsUtils {
@@ -46,10 +52,9 @@
private static int sThumbnailSize = -1;
- public static final boolean FLAG_N_FEATURE =
- false // Enforce Pre-N behavior in release build
- && (Build.VERSION.SDK_INT > Build.VERSION_CODES.M
- || Build.VERSION.CODENAME.startsWith("N"));
+ public static final boolean FLAG_N_FEATURE = SdkSelectionUtils.TARGET_N_SDK // build-time flag
+ && (Build.VERSION.SDK_INT > Build.VERSION_CODES.M // runtime flag
+ || Build.VERSION.CODENAME.startsWith("N")); // TODO: remove startsWith("N")
// TODO find a proper place for the canonical version of these
public interface ProviderNames {
@@ -96,6 +101,20 @@
return null;
}
+
+ public static final long USER_TYPE_CURRENT = 0;
+ public static final long USER_TYPE_WORK = 1;
+
+ /**
+ * UserType indicates the user type of the contact. If the contact is from Work User (Work
+ * Profile in Android Multi-User System), it's {@link #USER_TYPE_WORK}, otherwise,
+ * {@link #USER_TYPE_CURRENT}. Please note that current user can be in work profile, where the
+ * dialer is running inside Work Profile.
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef({USER_TYPE_CURRENT, USER_TYPE_WORK})
+ public @interface UserType {}
+
/**
* Test if the given {@link CharSequence} contains any graphic characters,
* first checking {@link TextUtils#isEmpty(CharSequence)} to handle null.
@@ -223,4 +242,49 @@
}
return new Pair<>(intent, secondaryIntent);
}
+
+ /**
+ * Determine UserType from directory id and contact id.
+ *
+ * 3 types of query
+ *
+ * 1. 2 profile query: content://com.android.contacts/phone_lookup_enterprise/1234567890
+ * personal and work contact are mixed into one cursor. no directory id. contact_id indicates if
+ * it's work contact
+ *
+ * 2. work local query:
+ * content://com.android.contacts/phone_lookup_enterprise/1234567890?directory=1000000000
+ * either directory_id or contact_id is enough to identify work contact
+ *
+ * 3. work remote query:
+ * content://com.android.contacts/phone_lookup_enterprise/1234567890?directory=1000000003
+ * contact_id is random. only directory_id is available
+ *
+ * Summary: If directory_id is not null, always use directory_id to identify work contact.
+ * (which is the case here) Otherwise, use contact_id.
+ *
+ * @param directoryId directory id of ContactsProvider query
+ * @param contactId contact id
+ * @return UserType indicates the user type of the contact. A directory id or contact id larger
+ * than a thredshold indicates that the contact is stored in Work Profile, but not in
+ * current user. It's a contract by ContactsProvider and check by
+ * Contacts.isEnterpriseDirectoryId and Contacts.isEnterpriseContactId. Currently, only
+ * 2 kinds of users can be detected from the directoryId and contactId as
+ * ContactsProvider can only access current and work user's contacts
+ */
+ public static @UserType long determineUserType(Long directoryId, Long contactId) {
+ // First check directory id
+ if (directoryId != null) {
+ return DirectoryCompat.isEnterpriseDirectoryId(directoryId) ? USER_TYPE_WORK
+ : USER_TYPE_CURRENT;
+ }
+ // Only check contact id if directory id is null
+ if (contactId != null && contactId != 0L
+ && ContactsCompat.isEnterpriseContactId(contactId)) {
+ return USER_TYPE_WORK;
+ } else {
+ return USER_TYPE_CURRENT;
+ }
+
+ }
}
diff --git a/src/com/android/contacts/common/activity/AppCompatTransactionSafeActivity.java b/src/com/android/contacts/common/activity/AppCompatTransactionSafeActivity.java
new file mode 100644
index 0000000..e70a9fd
--- /dev/null
+++ b/src/com/android/contacts/common/activity/AppCompatTransactionSafeActivity.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.contacts.common.activity;
+
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+
+/**
+ * A common superclass that keeps track of whether an {@link AppCompatActivity} has saved its state
+ * yet or not, copied from {@link com.android.contacts.common.activity.TransactionSafeActivity},
+ * which will be deprecated after Kitkat backporting is done.
+ */
+public abstract class AppCompatTransactionSafeActivity extends AppCompatActivity {
+
+ private boolean mIsSafeToCommitTransactions;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mIsSafeToCommitTransactions = true;
+ }
+
+ @Override
+ protected void onStart() {
+ super.onStart();
+ mIsSafeToCommitTransactions = true;
+ }
+
+ @Override
+ protected void onResume() {
+ super.onResume();
+ mIsSafeToCommitTransactions = true;
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ mIsSafeToCommitTransactions = false;
+ }
+
+ /**
+ * Returns true if it is safe to commit {@link FragmentTransaction}s at this time, based on
+ * whether {@link FragmentActivity#onSaveInstanceState} has been called or not.
+ *
+ * Make sure that the current activity calls into
+ * {@link super.onSaveInstanceState(Bundle outState)} (if that method is overridden),
+ * so the flag is properly set.
+ */
+ public boolean isSafeToCommitTransactions() {
+ return mIsSafeToCommitTransactions;
+ }
+}
diff --git a/src/com/android/contacts/common/compat/CallableCompat.java b/src/com/android/contacts/common/compat/CallableCompat.java
index 2979f63..d25d4be 100644
--- a/src/com/android/contacts/common/compat/CallableCompat.java
+++ b/src/com/android/contacts/common/compat/CallableCompat.java
@@ -28,8 +28,7 @@
Uri.withAppendedPath(Callable.CONTENT_URI, "filter_enterprise");
public static Uri getContentFilterUri() {
- // TODO: Use N APIs
- if (ContactsUtils.FLAG_N_FEATURE && android.os.Build.VERSION.CODENAME.startsWith("N")) {
+ if (ContactsUtils.FLAG_N_FEATURE) {
return ENTERPRISE_CONTENT_FILTER_URI;
}
return Callable.CONTENT_FILTER_URI;
diff --git a/src/com/android/contacts/common/compat/ContactsCompat.java b/src/com/android/contacts/common/compat/ContactsCompat.java
index 5b50385..5a5e46a 100644
--- a/src/com/android/contacts/common/compat/ContactsCompat.java
+++ b/src/com/android/contacts/common/compat/ContactsCompat.java
@@ -40,8 +40,7 @@
private static final long ENTERPRISE_CONTACT_ID_BASE = 1000000000;
public static Uri getContentUri() {
- // TODO: Use N APIs
- if (ContactsUtils.FLAG_N_FEATURE && android.os.Build.VERSION.CODENAME.startsWith("N")) {
+ if (ContactsUtils.FLAG_N_FEATURE) {
return ENTERPRISE_CONTENT_FILTER_URI;
}
return Contacts.CONTENT_FILTER_URI;
diff --git a/src/com/android/contacts/common/compat/DirectoryCompat.java b/src/com/android/contacts/common/compat/DirectoryCompat.java
index b032fe9..f100938 100644
--- a/src/com/android/contacts/common/compat/DirectoryCompat.java
+++ b/src/com/android/contacts/common/compat/DirectoryCompat.java
@@ -17,7 +17,6 @@
package com.android.contacts.common.compat;
import android.net.Uri;
-import android.os.Build;
import android.provider.ContactsContract;
import android.provider.ContactsContract.Directory;
@@ -25,30 +24,31 @@
public class DirectoryCompat {
- // TODO: Use N APIs
- private static final Uri ENTERPRISE_CONTENT_URI =
- Uri.withAppendedPath(ContactsContract.AUTHORITY_URI, "directories_enterprise");
- // TODO: Use N APIs
- private static final long ENTERPRISE_LOCAL_INVISIBLE = 1000000000L + Directory.LOCAL_INVISIBLE;
-
public static Uri getContentUri() {
- // TODO: Use N APIs
- if (ContactsUtils.FLAG_N_FEATURE && android.os.Build.VERSION.CODENAME.startsWith("N")) {
- return ENTERPRISE_CONTENT_URI;
+ if (ContactsUtils.FLAG_N_FEATURE) {
+ return DirectorySdkCompat.ENTERPRISE_CONTENT_URI;
}
return Directory.CONTENT_URI;
}
public static boolean isInvisibleDirectory(long directoryId) {
- return (directoryId == Directory.LOCAL_INVISIBLE
- || directoryId == ENTERPRISE_LOCAL_INVISIBLE);
+ if (ContactsUtils.FLAG_N_FEATURE) {
+ return (directoryId == Directory.LOCAL_INVISIBLE
+ || directoryId == DirectorySdkCompat.ENTERPRISE_LOCAL_INVISIBLE);
+ }
+ return directoryId == Directory.LOCAL_INVISIBLE;
}
public static boolean isRemoteDirectory(long directoryId) {
- // TODO: Use N APIs
- if (ContactsUtils.FLAG_N_FEATURE && android.os.Build.VERSION.CODENAME.startsWith("N")) {
- return Directory.isRemoteDirectory(directoryId);
+ if (ContactsUtils.FLAG_N_FEATURE) {
+ return DirectorySdkCompat.isRemoteDirectory(directoryId);
}
return !(directoryId == Directory.DEFAULT || directoryId == Directory.LOCAL_INVISIBLE);
}
+
+ public static boolean isEnterpriseDirectoryId(long directoryId) {
+ return ContactsUtils.FLAG_N_FEATURE
+ ? DirectorySdkCompat.isEnterpriseDirectoryId(directoryId)
+ : false;
+ }
}
diff --git a/src/com/android/contacts/common/compat/PhoneCompat.java b/src/com/android/contacts/common/compat/PhoneCompat.java
index 24600f5..5277761 100644
--- a/src/com/android/contacts/common/compat/PhoneCompat.java
+++ b/src/com/android/contacts/common/compat/PhoneCompat.java
@@ -28,8 +28,7 @@
Uri.withAppendedPath(Phone.CONTENT_URI, "filter_enterprise");
public static Uri getContentFilterUri() {
- // TODO: Use N APIs
- if (ContactsUtils.FLAG_N_FEATURE && android.os.Build.VERSION.CODENAME.startsWith("N")) {
+ if (ContactsUtils.FLAG_N_FEATURE) {
return ENTERPRISE_CONTENT_FILTER_URI;
}
return Phone.CONTENT_FILTER_URI;
diff --git a/src/com/android/contacts/common/dialog/CallSubjectDialog.java b/src/com/android/contacts/common/dialog/CallSubjectDialog.java
index 3c08b37..a17c4fc 100644
--- a/src/com/android/contacts/common/dialog/CallSubjectDialog.java
+++ b/src/com/android/contacts/common/dialog/CallSubjectDialog.java
@@ -48,6 +48,7 @@
import com.android.contacts.common.ContactPhotoManager;
import com.android.contacts.common.R;
import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.compat.PhoneAccountSdkCompat;
import com.android.contacts.common.compat.telecom.TelecomManagerCompat;
import com.android.contacts.common.util.UriUtils;
import com.android.phone.common.animation.AnimUtils;
@@ -593,17 +594,18 @@
(TelecomManager) getSystemService(Context.TELECOM_SERVICE);
final PhoneAccount account = telecomManager.getPhoneAccount(mPhoneAccountHandle);
- Bundle phoneAccountExtras = account.getExtras();
+ Bundle phoneAccountExtras = PhoneAccountSdkCompat.getExtras(account);
if (phoneAccountExtras == null) {
return;
}
// Get limit, if provided; otherwise default to existing value.
- mLimit = phoneAccountExtras.getInt(PhoneAccount.EXTRA_CALL_SUBJECT_MAX_LENGTH, mLimit);
+ mLimit = phoneAccountExtras
+ .getInt(PhoneAccountSdkCompat.EXTRA_CALL_SUBJECT_MAX_LENGTH, mLimit);
// Get charset; default to none (e.g. count characters 1:1).
String charsetName = phoneAccountExtras.getString(
- PhoneAccount.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING);
+ PhoneAccountSdkCompat.EXTRA_CALL_SUBJECT_CHARACTER_ENCODING);
if (!TextUtils.isEmpty(charsetName)) {
try {
diff --git a/src/com/android/contacts/common/list/AccountFilterActivity.java b/src/com/android/contacts/common/list/AccountFilterActivity.java
index 20be63b..966637b 100644
--- a/src/com/android/contacts/common/list/AccountFilterActivity.java
+++ b/src/com/android/contacts/common/list/AccountFilterActivity.java
@@ -63,6 +63,10 @@
private ContactListFilter mCurrentFilter;
+ private ContactListFilterView mCustomFilterView; // the "Customize" filter
+
+ private boolean mIsCustomFilterViewSelected;
+
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
@@ -170,6 +174,8 @@
final ContactListFilter filter = (ContactListFilter) view.getTag();
if (filter == null) return; // Just in case
if (filter.filterType == ContactListFilter.FILTER_TYPE_CUSTOM) {
+ mCustomFilterView = listFilterView;
+ mIsCustomFilterViewSelected = listFilterView.isChecked();
final Intent intent = new Intent(this,
CustomContactListFilterActivity.class);
listFilterView.setActivated(true);
@@ -190,6 +196,12 @@
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ if (resultCode == AppCompatActivity.RESULT_CANCELED && mCustomFilterView != null &&
+ !mIsCustomFilterViewSelected) {
+ mCustomFilterView.setActivated(false);
+ return;
+ }
+
if (resultCode != AppCompatActivity.RESULT_OK) {
return;
}
diff --git a/src/com/android/contacts/common/list/ContactEntryListAdapter.java b/src/com/android/contacts/common/list/ContactEntryListAdapter.java
index 089288b..a7c3504 100644
--- a/src/com/android/contacts/common/list/ContactEntryListAdapter.java
+++ b/src/com/android/contacts/common/list/ContactEntryListAdapter.java
@@ -418,9 +418,17 @@
DirectoryPartition partition = new DirectoryPartition(false, true);
partition.setDirectoryId(id);
if (DirectoryCompat.isRemoteDirectory(id)) {
- partition.setLabel(mContext.getString(R.string.directory_search_label));
+ if (DirectoryCompat.isEnterpriseDirectoryId(id)) {
+ partition.setLabel(mContext.getString(R.string.directory_search_label_work));
+ } else {
+ partition.setLabel(mContext.getString(R.string.directory_search_label));
+ }
} else {
- partition.setLabel(mDefaultFilterHeaderText.toString());
+ if (DirectoryCompat.isEnterpriseDirectoryId(id)) {
+ partition.setLabel(mContext.getString(R.string.list_filter_phones_work));
+ } else {
+ partition.setLabel(mDefaultFilterHeaderText.toString());
+ }
}
partition.setDirectoryType(cursor.getString(directoryTypeColumnIndex));
partition.setDisplayName(cursor.getString(displayNameColumnIndex));
diff --git a/src/com/android/contacts/common/list/ContactListFilterView.java b/src/com/android/contacts/common/list/ContactListFilterView.java
index c6cc597..6df8e21 100644
--- a/src/com/android/contacts/common/list/ContactListFilterView.java
+++ b/src/com/android/contacts/common/list/ContactListFilterView.java
@@ -78,6 +78,10 @@
setContentDescription(generateContentDescription());
}
+ public boolean isChecked() {
+ return mRadioButton.isChecked();
+ }
+
public void bindView(AccountTypeManager accountTypes) {
if (mAccountType == null) {
mIcon = (ImageView) findViewById(R.id.icon);
diff --git a/src/com/android/contacts/common/list/ContactListItemView.java b/src/com/android/contacts/common/list/ContactListItemView.java
index 18e82ad..90b3d60 100644
--- a/src/com/android/contacts/common/list/ContactListItemView.java
+++ b/src/com/android/contacts/common/list/ContactListItemView.java
@@ -31,6 +31,7 @@
import android.provider.ContactsContract.Contacts;
import android.support.v4.content.ContextCompat;
import android.support.v4.graphics.drawable.DrawableCompat;
+import android.support.v7.widget.AppCompatCheckBox;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.TextUtils;
@@ -43,7 +44,6 @@
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView.SelectionBoundsAdjuster;
-import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.QuickContactBadge;
@@ -185,8 +185,9 @@
private TextView mSnippetView;
private TextView mStatusView;
private ImageView mPresenceIcon;
- private CheckBox mCheckBox;
+ private AppCompatCheckBox mCheckBox;
private ImageView mVideoCallIcon;
+ private ImageView mWorkProfileIcon;
private ColorStateList mSecondaryTextColor;
@@ -537,6 +538,14 @@
MeasureSpec.makeMeasureSpec(mVideoCallIconSize, MeasureSpec.EXACTLY));
}
+ if (isVisible(mWorkProfileIcon)) {
+ mWorkProfileIcon.measure(
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
+ MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
+ mNameTextViewHeight =
+ Math.max(mNameTextViewHeight, mWorkProfileIcon.getMeasuredHeight());
+ }
+
if (isVisible(mStatusView)) {
// Presence and status are in a same row, so status will be affected by icon size.
final int statusWidth;
@@ -706,11 +715,32 @@
mLabelAndDataViewMaxHeight + mSnippetTextViewHeight + mStatusTextViewHeight;
int textTopBound = (bottomBound + topBound - totalTextHeight) / 2 + mTextOffsetTop;
+ // Work Profile icon align top
+ int workProfileIconWidth = 0;
+ if (isVisible(mWorkProfileIcon)) {
+ workProfileIconWidth = mWorkProfileIcon.getMeasuredWidth();
+ final int distanceFromEnd = mCheckBoxWidth > 0
+ ? mCheckBoxWidth + mGapBetweenImageAndText : 0;
+ if (mPhotoPosition == PhotoPosition.LEFT) {
+ // When photo is on left, label is placed on the right edge of the list item.
+ mWorkProfileIcon.layout(rightBound - workProfileIconWidth - distanceFromEnd,
+ textTopBound,
+ rightBound - distanceFromEnd,
+ textTopBound + mNameTextViewHeight);
+ } else {
+ // When photo is on right, label is placed on the left of data view.
+ mWorkProfileIcon.layout(leftBound + distanceFromEnd,
+ textTopBound,
+ leftBound + workProfileIconWidth + distanceFromEnd,
+ textTopBound + mNameTextViewHeight);
+ }
+ }
+
// Layout all text view and presence icon
// Put name TextView first
if (isVisible(mNameTextView)) {
- final int distanceFromEnd = mCheckBoxWidth > 0
- ? mCheckBoxWidth + mGapBetweenImageAndText : 0;
+ final int distanceFromEnd = workProfileIconWidth
+ + (mCheckBoxWidth > 0 ? mCheckBoxWidth + mGapBetweenImageAndText : 0);
if (mPhotoPosition == PhotoPosition.LEFT) {
mNameTextView.layout(leftBound,
textTopBound,
@@ -722,6 +752,9 @@
rightBound,
textTopBound + mNameTextViewHeight);
}
+ }
+
+ if (isVisible(mNameTextView) || isVisible(mWorkProfileIcon)) {
textTopBound += mNameTextViewHeight;
}
@@ -1198,11 +1231,11 @@
}
/**
- * Returns the {@link CheckBox} view, creating it if necessary.
+ * Returns the {@link AppCompatCheckBox} view, creating it if necessary.
*/
- public CheckBox getCheckBox() {
+ public AppCompatCheckBox getCheckBox() {
if (mCheckBox == null) {
- mCheckBox = new CheckBox(getContext());
+ mCheckBox = new AppCompatCheckBox(getContext());
// Make non-focusable, so the rest of the ContactListItemView can be clicked.
mCheckBox.setFocusable(false);
addView(mCheckBox);
@@ -1318,6 +1351,23 @@
}
}
+ /**
+ * Set to display work profile icon or not
+ *
+ * @param enabled set to display work profile icon or not
+ */
+ public void setWorkProfileIconEnabled(boolean enabled) {
+ if (mWorkProfileIcon != null) {
+ mWorkProfileIcon.setVisibility(enabled ? View.VISIBLE : View.GONE);
+ } else if (enabled) {
+ mWorkProfileIcon = new ImageView(getContext());
+ addView(mWorkProfileIcon);
+ mWorkProfileIcon.setImageResource(R.drawable.ic_work_profile);
+ mWorkProfileIcon.setScaleType(ScaleType.CENTER_INSIDE);
+ mWorkProfileIcon.setVisibility(View.VISIBLE);
+ }
+ }
+
private TruncateAt getTextEllipsis() {
return TruncateAt.MARQUEE;
}
diff --git a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
index fc90fbf..9e886d9 100644
--- a/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
+++ b/src/com/android/contacts/common/list/PhoneNumberListAdapter.java
@@ -35,6 +35,7 @@
import com.android.contacts.common.CallUtil;
import com.android.contacts.common.ContactPhotoManager.DefaultImageRequest;
+import com.android.contacts.common.ContactsUtils;
import com.android.contacts.common.GeoUtil;
import com.android.contacts.common.R;
import com.android.contacts.common.compat.CallableCompat;
@@ -321,11 +322,20 @@
public Uri getDataUri(int partitionIndex, Cursor cursor) {
final long directoryId =
((DirectoryPartition)getPartition(partitionIndex)).getDirectoryId();
- if (!DirectoryCompat.isRemoteDirectory(directoryId)) {
+ if (DirectoryCompat.isRemoteDirectory(directoryId)) {
+ return null;
+ } else if (DirectoryCompat.isEnterpriseDirectoryId(directoryId)) {
+ /*
+ * ContentUris.withAppendedId(Data.CONTENT_URI, phoneId), is invalid if
+ * isEnterpriseDirectoryId returns true, because the uri itself will fail since the
+ * ContactsProvider in Android Framework currently doesn't support it. return null until
+ * Android framework has enterprise version of Data.CONTENT_URI
+ */
+ return null;
+ } else {
final long phoneId = cursor.getLong(PhoneQuery.PHONE_ID);
return ContentUris.withAppendedId(Data.CONTENT_URI, phoneId);
}
- return null;
}
/**
@@ -427,6 +437,7 @@
view.removePhotoView(true, false);
}
+ bindWorkProfileIcon(view, partition);
final DirectoryPartition directory = (DirectoryPartition) getPartition(partition);
bindPhoneNumber(view, cursor, directory.isDisplayNumber(), position);
@@ -485,6 +496,13 @@
view.hideDisplayName();
}
+ private void bindWorkProfileIcon(final ContactListItemView view, int partition) {
+ final DirectoryPartition directory = (DirectoryPartition) getPartition(partition);
+ final long directoryId = directory.getDirectoryId();
+ final long userType = ContactsUtils.determineUserType(directoryId, null);
+ view.setWorkProfileIconEnabled(userType == ContactsUtils.USER_TYPE_WORK);
+ }
+
protected void bindPhoto(final ContactListItemView view, int partitionIndex, Cursor cursor) {
if (!isPhotoSupported(partitionIndex)) {
view.removePhotoView();
diff --git a/src/com/android/contacts/common/model/ContactLoader.java b/src/com/android/contacts/common/model/ContactLoader.java
index 923e2f9..f925d1d 100644
--- a/src/com/android/contacts/common/model/ContactLoader.java
+++ b/src/com/android/contacts/common/model/ContactLoader.java
@@ -40,6 +40,7 @@
import com.android.contacts.common.GeoUtil;
import com.android.contacts.common.GroupMetaData;
+import com.android.contacts.common.compat.CompatUtils;
import com.android.contacts.common.model.account.AccountType;
import com.android.contacts.common.model.account.AccountTypeWithDataSet;
import com.android.contacts.common.util.Constants;
@@ -51,6 +52,7 @@
import com.android.contacts.common.model.dataitem.PhotoDataItem;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
@@ -113,7 +115,7 @@
* social stream items).
*/
private static class ContactQuery {
- static final String[] COLUMNS = new String[] {
+ static final String[] COLUMNS_INTERNAL = new String[] {
Contacts.NAME_RAW_CONTACT_ID,
Contacts.DISPLAY_NAME_SOURCE,
Contacts.LOOKUP_KEY,
@@ -183,10 +185,19 @@
Contacts.IS_USER_PROFILE,
Data.TIMES_USED,
- Data.LAST_TIME_USED,
- Data.CARRIER_PRESENCE
+ Data.LAST_TIME_USED
};
+ static final String[] COLUMNS;
+
+ static {
+ List<String> projectionList = Lists.newArrayList(COLUMNS_INTERNAL);
+ if (CompatUtils.isMarshmallowCompatible()) {
+ projectionList.add(Data.CARRIER_PRESENCE);
+ }
+ COLUMNS = projectionList.toArray(new String[projectionList.size()]);
+ }
+
public static final int NAME_RAW_CONTACT_ID = 0;
public static final int DISPLAY_NAME_SOURCE = 1;
public static final int LOOKUP_KEY = 2;
@@ -716,7 +727,9 @@
cursorColumnToContentValues(cursor, cv, ContactQuery.CHAT_CAPABILITY);
cursorColumnToContentValues(cursor, cv, ContactQuery.TIMES_USED);
cursorColumnToContentValues(cursor, cv, ContactQuery.LAST_TIME_USED);
- cursorColumnToContentValues(cursor, cv, ContactQuery.CARRIER_PRESENCE);
+ if (CompatUtils.isMarshmallowCompatible()) {
+ cursorColumnToContentValues(cursor, cv, ContactQuery.CARRIER_PRESENCE);
+ }
return cv;
}
diff --git a/src/com/android/contacts/common/model/account/BaseAccountType.java b/src/com/android/contacts/common/model/account/BaseAccountType.java
index 7526f0c..214ba77 100644
--- a/src/com/android/contacts/common/model/account/BaseAccountType.java
+++ b/src/com/android/contacts/common/model/account/BaseAccountType.java
@@ -119,7 +119,7 @@
this.accountType = null;
this.dataSet = null;
this.titleRes = R.string.account_phone;
- this.iconRes = R.mipmap.ic_contacts_clr_48cv_44dp;
+ this.iconRes = R.mipmap.ic_contacts_launcher;
}
protected static EditType buildPhoneType(int type) {
diff --git a/src/com/android/contacts/common/model/account/FallbackAccountType.java b/src/com/android/contacts/common/model/account/FallbackAccountType.java
index fd81e46..ce1d059 100644
--- a/src/com/android/contacts/common/model/account/FallbackAccountType.java
+++ b/src/com/android/contacts/common/model/account/FallbackAccountType.java
@@ -30,7 +30,7 @@
this.accountType = null;
this.dataSet = null;
this.titleRes = R.string.account_phone;
- this.iconRes = R.mipmap.ic_contacts_clr_48cv_44dp;
+ this.iconRes = R.mipmap.ic_contacts_launcher;
// Note those are only set for unit tests.
this.resourcePackageName = resPackageName;
diff --git a/src/com/android/contacts/common/widget/FloatingActionButtonController.java b/src/com/android/contacts/common/widget/FloatingActionButtonController.java
index eb69d3c..c943669 100644
--- a/src/com/android/contacts/common/widget/FloatingActionButtonController.java
+++ b/src/com/android/contacts/common/widget/FloatingActionButtonController.java
@@ -24,8 +24,9 @@
import android.view.View;
import android.widget.ImageButton;
-import com.android.contacts.common.util.ViewUtil;
import com.android.contacts.common.R;
+import com.android.contacts.common.compat.CompatUtils;
+import com.android.contacts.common.util.ViewUtil;
import com.android.phone.common.animation.AnimUtils;
/**
@@ -50,8 +51,14 @@
public FloatingActionButtonController(Activity activity, View container, ImageButton button) {
Resources resources = activity.getResources();
- mFabInterpolator = AnimationUtils.loadInterpolator(activity,
- android.R.interpolator.fast_out_slow_in);
+ if (CompatUtils.isLollipopCompatible()) {
+ mFabInterpolator = AnimationUtils.loadInterpolator(activity,
+ android.R.interpolator.fast_out_slow_in);
+ } else {
+ // Use linear to avoid crash on Kitkat since fast_out_slow_in was added in API level 21
+ mFabInterpolator = AnimationUtils.loadInterpolator(activity,
+ android.R.interpolator.linear);
+ }
mFloatingActionButtonWidth = resources.getDimensionPixelSize(
R.dimen.floating_action_button_width);
mFloatingActionButtonMarginRight = resources.getDimensionPixelOffset(
@@ -104,7 +111,6 @@
// moves along with it.
mFloatingActionButtonContainer.setTranslationX(
(int) (positionOffset * getTranslationXForAlignment(ALIGN_END)));
- mFloatingActionButtonContainer.setTranslationY(0);
}
/**