Merge "Improve D-Pad accessiblity of the call details."
diff --git a/res/layout/editor_account_header.xml b/res/layout/editor_account_header.xml
index ff33cf1..6dd55fd 100644
--- a/res/layout/editor_account_header.xml
+++ b/res/layout/editor_account_header.xml
@@ -38,18 +38,20 @@
<TextView
android:id="@+id/account_type"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:singleLine="true" />
+ android:singleLine="true"
+ android:ellipsize="end" />
<TextView
android:id="@+id/account_name"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorTertiary"
- android:singleLine="true" />
+ android:singleLine="true"
+ android:ellipsize="end" />
</LinearLayout>
diff --git a/res/layout/editor_account_header_with_dropdown.xml b/res/layout/editor_account_header_with_dropdown.xml
index 001eaae..12c2a84 100644
--- a/res/layout/editor_account_header_with_dropdown.xml
+++ b/res/layout/editor_account_header_with_dropdown.xml
@@ -29,37 +29,35 @@
<LinearLayout
android:id="@+id/account"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="0dip"
+ android:layout_weight="1"
android:orientation="vertical"
style="?android:attr/spinnerStyle">
<TextView
android:id="@+id/account_type"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:singleLine="true" />
+ android:singleLine="true"
+ android:ellipsize="end" />
<TextView
android:id="@+id/account_name"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingRight="8dip"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorTertiary"
- android:singleLine="true" />
+ android:singleLine="true"
+ android:ellipsize="end" />
</LinearLayout>
- <!-- Spacer between the account type / name dropdown and the account icon -->
- <View
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"/>
-
<FrameLayout
android:layout_width="wrap_content"
- android:layout_height="match_parent">
+ android:layout_height="match_parent"
+ android:layout_marginLeft="10dip">
<ImageView
android:id="@+id/account_icon"
diff --git a/res/layout/user_profile_header.xml b/res/layout/user_profile_header.xml
index ff01a11..6867dea 100644
--- a/res/layout/user_profile_header.xml
+++ b/res/layout/user_profile_header.xml
@@ -40,6 +40,7 @@
android:ellipsize="end"
android:gravity="left|center_vertical"
android:layout_weight="1"
+ android:textAllCaps="true"
android:textAppearance="?android:attr/textAppearanceSmall"
android:paddingLeft="?attr/list_item_text_indent"
android:textColor="@color/people_app_theme_color" />
@@ -52,7 +53,7 @@
android:ellipsize="end"
android:layout_gravity="right|center_vertical"
android:textAppearance="?android:attr/textAppearanceSmall"
- android:textSize="12dip"
+ android:textSize="12sp"
android:textColor="@color/contact_count_text_color" />
</LinearLayout>
diff --git a/res/values/styles.xml b/res/values/styles.xml
index 24822c0..6a64dfd 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -142,7 +142,7 @@
<item name="list_item_profile_photo_size">70dip</item>
<item name="list_item_prefix_highlight_color">#99cc00</item>
<item name="list_item_header_text_color">@color/people_app_theme_color</item>
- <item name="list_item_header_text_size">14dip</item>
+ <item name="list_item_header_text_size">14sp</item>
<item name="list_item_header_height">26dip</item>
<item name="list_item_header_underline_height">1dip</item>
<item name="list_item_header_underline_color">@color/people_app_theme_color</item>
diff --git a/src/com/android/contacts/detail/ContactDetailFragment.java b/src/com/android/contacts/detail/ContactDetailFragment.java
index 456abe8..a7a1ba1 100644
--- a/src/com/android/contacts/detail/ContactDetailFragment.java
+++ b/src/com/android/contacts/detail/ContactDetailFragment.java
@@ -550,7 +550,7 @@
mRawContactIds.add(rawContactId);
}
AccountType type = accountTypes.getAccountType(accountType, dataSet);
- if (type == null || !type.readOnly) {
+ if (type == null || type.areContactsWritable()) {
mWritableRawContactIds.add(rawContactId);
}
@@ -1948,7 +1948,7 @@
AccountTypeManager.getInstance(mContext);
final AccountType type = accountTypes.getAccountType(accountType, dataSet);
// Offline or non-writeable account? Nothing to fix
- if (type == null || type.readOnly) return false;
+ if (type == null || !type.areContactsWritable()) return false;
// Check whether the contact is in the default group
boolean isInDefaultGroup = false;
diff --git a/src/com/android/contacts/editor/AggregationSuggestionView.java b/src/com/android/contacts/editor/AggregationSuggestionView.java
index 996dbc4..9d7e16a 100644
--- a/src/com/android/contacts/editor/AggregationSuggestionView.java
+++ b/src/com/android/contacts/editor/AggregationSuggestionView.java
@@ -120,7 +120,7 @@
return true;
}
AccountType type = accountTypes.getAccountType(accountType, dataSet);
- if (!type.readOnly) {
+ if (type.areContactsWritable()) {
return true;
}
}
diff --git a/src/com/android/contacts/editor/ContactEditorFragment.java b/src/com/android/contacts/editor/ContactEditorFragment.java
index 2e54642..22fc3fc 100644
--- a/src/com/android/contacts/editor/ContactEditorFragment.java
+++ b/src/com/android/contacts/editor/ContactEditorFragment.java
@@ -519,7 +519,7 @@
final String accountType = state.getValues().getAsString(RawContacts.ACCOUNT_TYPE);
final String dataSet = state.getValues().getAsString(RawContacts.DATA_SET);
final AccountType type = accountTypes.getAccountType(accountType, dataSet);
- if (!type.readOnly) {
+ if (type.areContactsWritable()) {
// Apply extras to the first writable raw contact only
EntityModifier.parseExtras(mContext, type, state, extras);
break;
@@ -698,7 +698,7 @@
editor.setState(entity, type, mViewIdGenerator, isEditingUserProfile());
editor.getPhotoEditor().setEditorListener(
- new PhotoEditorListener(editor, type.readOnly));
+ new PhotoEditorListener(editor, type.areContactsWritable()));
if (editor instanceof RawContactEditorView) {
final RawContactEditorView rawContactEditor = (RawContactEditorView) editor;
EditorListener listener = new EditorListener() {
@@ -1154,7 +1154,7 @@
final String accountType = values.getAsString(RawContacts.ACCOUNT_TYPE);
final String dataSet = values.getAsString(RawContacts.DATA_SET);
final AccountType type = accountTypes.getAccountType(accountType, dataSet);
- if (!type.readOnly) {
+ if (type.areContactsWritable()) {
return true;
}
}
@@ -1234,9 +1234,9 @@
final AccountType type2 = accountTypes.getAccountType(accountType2, dataSet2);
// Check read-only
- if (type1.readOnly && !type2.readOnly) {
+ if (!type1.areContactsWritable() && type2.areContactsWritable()) {
return 1;
- } else if (!type1.readOnly && type2.readOnly) {
+ } else if (type1.areContactsWritable() && !type2.areContactsWritable()) {
return -1;
}
@@ -1693,11 +1693,11 @@
private final class PhotoEditorListener
implements EditorListener, PhotoActionPopup.Listener {
private final BaseRawContactEditorView mEditor;
- private final boolean mAccountReadOnly;
+ private final boolean mAccountWritable;
- private PhotoEditorListener(BaseRawContactEditorView editor, boolean accountReadOnly) {
+ private PhotoEditorListener(BaseRawContactEditorView editor, boolean accountWritable) {
mEditor = editor;
- mAccountReadOnly = accountReadOnly;
+ mAccountWritable = accountWritable;
}
@Override
@@ -1707,14 +1707,7 @@
if (request == EditorListener.REQUEST_PICK_PHOTO) {
// Determine mode
final int mode;
- if (mAccountReadOnly) {
- if (mEditor.hasSetPhoto() && hasMoreThanOnePhoto()) {
- mode = PhotoActionPopup.MODE_READ_ONLY_ALLOW_PRIMARY;
- } else {
- // Read-only and either no photo or the only photo ==> no options
- return;
- }
- } else {
+ if (mAccountWritable) {
if (mEditor.hasSetPhoto()) {
if (hasMoreThanOnePhoto()) {
mode = PhotoActionPopup.MODE_PHOTO_ALLOW_PRIMARY;
@@ -1724,6 +1717,13 @@
} else {
mode = PhotoActionPopup.MODE_NO_PHOTO;
}
+ } else {
+ if (mEditor.hasSetPhoto() && hasMoreThanOnePhoto()) {
+ mode = PhotoActionPopup.MODE_READ_ONLY_ALLOW_PRIMARY;
+ } else {
+ // Read-only and either no photo or the only photo ==> no options
+ return;
+ }
}
PhotoActionPopup.createPopupMenu(mContext, mEditor.getPhotoEditor(), this, mode)
.show();
diff --git a/src/com/android/contacts/editor/ExternalRawContactEditorView.java b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
index 9b4f988..b95a742 100644
--- a/src/com/android/contacts/editor/ExternalRawContactEditorView.java
+++ b/src/com/android/contacts/editor/ExternalRawContactEditorView.java
@@ -148,8 +148,12 @@
accountType = mContext.getString(R.string.account_phone);
}
if (!TextUtils.isEmpty(mAccountName)) {
+ mAccountNameTextView.setVisibility(View.VISIBLE);
mAccountNameTextView.setText(
mContext.getString(R.string.from_account_format, mAccountName));
+ } else {
+ // Hide this view so the other text view will be centered vertically
+ mAccountNameTextView.setVisibility(View.GONE);
}
mAccountTypeTextView.setText(mContext.getString(R.string.account_type_format,
accountType));
@@ -172,7 +176,7 @@
boolean hasPhotoEditor = type.getKindForMimetype(Photo.CONTENT_ITEM_TYPE) != null;
setHasPhotoEditor(hasPhotoEditor);
primary = state.getPrimaryEntry(Photo.CONTENT_ITEM_TYPE);
- getPhotoEditor().setValues(kind, primary, state, type.readOnly, vig);
+ getPhotoEditor().setValues(kind, primary, state, !type.areContactsWritable(), vig);
if (!hasPhotoEditor || !getPhotoEditor().hasSetPhoto()) {
mPhotoStub.setVisibility(View.GONE);
} else {
@@ -187,7 +191,11 @@
mName.setText(primary != null ? primary.getAsString(StructuredName.DISPLAY_NAME) :
mContext.getString(R.string.missing_name));
- if (type.readOnly) {
+ if (type.areContactsWritable()) {
+ mAccountContainer.setBackgroundDrawable(null);
+ mAccountContainer.setEnabled(false);
+ mEditExternallyButton.setVisibility(View.VISIBLE);
+ } else {
mAccountContainer.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -196,10 +204,6 @@
}
});
mEditExternallyButton.setVisibility(View.GONE);
- } else {
- mAccountContainer.setBackgroundDrawable(null);
- mAccountContainer.setEnabled(false);
- mEditExternallyButton.setVisibility(View.VISIBLE);
}
final Resources res = mContext.getResources();
diff --git a/src/com/android/contacts/editor/RawContactEditorView.java b/src/com/android/contacts/editor/RawContactEditorView.java
index 2d42a50..3a40a0f 100644
--- a/src/com/android/contacts/editor/RawContactEditorView.java
+++ b/src/com/android/contacts/editor/RawContactEditorView.java
@@ -195,8 +195,12 @@
accountType = mContext.getString(R.string.account_phone);
}
if (!TextUtils.isEmpty(accountName)) {
+ mAccountNameTextView.setVisibility(View.VISIBLE);
mAccountNameTextView.setText(
mContext.getString(R.string.from_account_format, accountName));
+ } else {
+ // Hide this view so the other text view will be centered vertically
+ mAccountNameTextView.setVisibility(View.GONE);
}
mAccountTypeTextView.setText(
mContext.getString(R.string.account_type_format, accountType));
diff --git a/src/com/android/contacts/interactions/ContactDeletionInteraction.java b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
index 86f4eda..7e880a4 100644
--- a/src/com/android/contacts/interactions/ContactDeletionInteraction.java
+++ b/src/com/android/contacts/interactions/ContactDeletionInteraction.java
@@ -240,11 +240,11 @@
contactId = cursor.getLong(COLUMN_INDEX_CONTACT_ID);
lookupKey = cursor.getString(COLUMN_INDEX_LOOKUP_KEY);
AccountType type = accountTypes.getAccountType(accountType, dataSet);
- boolean readonly = type != null && type.readOnly;
- if (readonly) {
- readOnlyRawContacts.add(rawContactId);
- } else {
+ boolean writable = type == null || type.areContactsWritable();
+ if (writable) {
writableRawContacts.add(rawContactId);
+ } else {
+ readOnlyRawContacts.add(rawContactId);
}
}
diff --git a/src/com/android/contacts/model/AccountType.java b/src/com/android/contacts/model/AccountType.java
index 879a89f..eef8049 100644
--- a/src/com/android/contacts/model/AccountType.java
+++ b/src/com/android/contacts/model/AccountType.java
@@ -71,8 +71,6 @@
public int titleRes;
public int iconRes;
- public boolean readOnly;
-
/**
* Set of {@link DataKind} supported by this source.
*/
@@ -92,6 +90,11 @@
}
/**
+ * @return True if contacts can be created and edited using this app
+ */
+ public abstract boolean areContactsWritable();
+
+ /**
* Returns an optional custom edit activity. The activity class should reside
* in the sync adapter package as determined by {@link #resPackageName}.
*/
diff --git a/src/com/android/contacts/model/AccountTypeManager.java b/src/com/android/contacts/model/AccountTypeManager.java
index 33d6c97..bdd8a50 100644
--- a/src/com/android/contacts/model/AccountTypeManager.java
+++ b/src/com/android/contacts/model/AccountTypeManager.java
@@ -329,7 +329,6 @@
// Skip external account types that couldn't be initialized.
continue;
}
- accountType.readOnly = !sync.supportsUploading();
}
accountType.accountType = auth.type;
@@ -395,7 +394,7 @@
AccountWithDataSet accountWithDataSet = new AccountWithDataSet(
account.name, account.type, accountType.dataSet);
allAccounts.add(accountWithDataSet);
- if (!accountType.readOnly) {
+ if (accountType.areContactsWritable()) {
writableAccounts.add(accountWithDataSet);
}
}
diff --git a/src/com/android/contacts/model/BaseAccountType.java b/src/com/android/contacts/model/BaseAccountType.java
index e6c0400..b599c66 100644
--- a/src/com/android/contacts/model/BaseAccountType.java
+++ b/src/com/android/contacts/model/BaseAccountType.java
@@ -40,7 +40,7 @@
import android.provider.ContactsContract.CommonDataKinds.Website;
import android.view.inputmethod.EditorInfo;
-public class BaseAccountType extends AccountType {
+public abstract class BaseAccountType extends AccountType {
protected static final int FLAGS_PHONE = EditorInfo.TYPE_CLASS_PHONE;
protected static final int FLAGS_EMAIL = EditorInfo.TYPE_CLASS_TEXT
| EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS;
diff --git a/src/com/android/contacts/model/ExchangeAccountType.java b/src/com/android/contacts/model/ExchangeAccountType.java
index 240df47..4a0e7a0 100644
--- a/src/com/android/contacts/model/ExchangeAccountType.java
+++ b/src/com/android/contacts/model/ExchangeAccountType.java
@@ -339,4 +339,9 @@
public boolean isGroupMembershipEditable() {
return true;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
}
diff --git a/src/com/android/contacts/model/ExternalAccountType.java b/src/com/android/contacts/model/ExternalAccountType.java
index 7fefc44..9718ce2 100644
--- a/src/com/android/contacts/model/ExternalAccountType.java
+++ b/src/com/android/contacts/model/ExternalAccountType.java
@@ -65,7 +65,6 @@
// The following attributes should only be set in non-sync-adapter account types. They allow
// for the account type and resource IDs to be specified without an associated authenticator.
private static final String ATTR_ACCOUNT_TYPE = "accountType";
- private static final String ATTR_READ_ONLY = "readOnly";
private static final String ATTR_ACCOUNT_LABEL = "accountTypeLabel";
private static final String ATTR_ACCOUNT_ICON = "accountTypeIcon";
@@ -143,6 +142,11 @@
return mInitSuccessful;
}
+ @Override
+ public boolean areContactsWritable() {
+ return getCreateContactActivityClassName() != null;
+ }
+
/**
* Whether this account type has the android.provider.CONTACTS_STRUCTURE metadata xml.
*/
@@ -251,8 +255,6 @@
mExtensionPackageNames.add(value);
} else if (ATTR_ACCOUNT_TYPE.equals(attr)) {
accountType = value;
- } else if (ATTR_READ_ONLY.equals(attr)) {
- readOnly = !"0".equals(value) && !"false".equals(value);
} else if (ATTR_ACCOUNT_LABEL.equals(attr)) {
mAccountTypeLabelAttribute = value;
} else if (ATTR_ACCOUNT_ICON.equals(attr)) {
diff --git a/src/com/android/contacts/model/FallbackAccountType.java b/src/com/android/contacts/model/FallbackAccountType.java
index 8bb3992..3b56b04 100644
--- a/src/com/android/contacts/model/FallbackAccountType.java
+++ b/src/com/android/contacts/model/FallbackAccountType.java
@@ -55,4 +55,9 @@
public int getSideBarColor(Context context) {
return 0xffbdc7b8;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
}
diff --git a/src/com/android/contacts/model/GoogleAccountType.java b/src/com/android/contacts/model/GoogleAccountType.java
index a5fab96..cee43dd 100644
--- a/src/com/android/contacts/model/GoogleAccountType.java
+++ b/src/com/android/contacts/model/GoogleAccountType.java
@@ -183,4 +183,9 @@
public boolean isGroupMembershipEditable() {
return true;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
}
diff --git a/tests/src/com/android/contacts/ContactLoaderTest.java b/tests/src/com/android/contacts/ContactLoaderTest.java
index 5d44cf1..f88b64e 100644
--- a/tests/src/com/android/contacts/ContactLoaderTest.java
+++ b/tests/src/com/android/contacts/ContactLoaderTest.java
@@ -51,7 +51,12 @@
mContactsProvider = mMockContext.getContactsProvider();
InjectedServices services = new InjectedServices();
- AccountType accountType = new BaseAccountType();
+ AccountType accountType = new BaseAccountType() {
+ @Override
+ public boolean areContactsWritable() {
+ return false;
+ }
+ };
accountType.accountType = "mockAccountType";
AccountWithDataSet account =
diff --git a/tests/src/com/android/contacts/EntityModifierTests.java b/tests/src/com/android/contacts/EntityModifierTests.java
index cf6fefe..76d3d84 100644
--- a/tests/src/com/android/contacts/EntityModifierTests.java
+++ b/tests/src/com/android/contacts/EntityModifierTests.java
@@ -153,6 +153,11 @@
public boolean isGroupMembershipEditable() {
return false;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
}
/**
diff --git a/tests/src/com/android/contacts/activities/PeopleActivityTest.java b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
index f419842..66c2c5a 100644
--- a/tests/src/com/android/contacts/activities/PeopleActivityTest.java
+++ b/tests/src/com/android/contacts/activities/PeopleActivityTest.java
@@ -94,7 +94,12 @@
services.setSharedPreferences(new MockSharedPreferences());
services.setSystemService(ContactPhotoManager.CONTACT_PHOTO_SERVICE,
new MockContactPhotoManager());
- AccountType accountType = new BaseAccountType();
+ AccountType accountType = new BaseAccountType() {
+ @Override
+ public boolean areContactsWritable() {
+ return false;
+ }
+ };
accountType.accountType = TEST_ACCOUNT_TYPE;
AccountWithDataSet account = new AccountWithDataSet(TEST_ACCOUNT, TEST_ACCOUNT_TYPE, null);
diff --git a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
index a6222db..2c4b74c 100644
--- a/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
+++ b/tests/src/com/android/contacts/interactions/ContactDeletionInteractionTest.java
@@ -83,11 +83,20 @@
InjectedServices services = new InjectedServices();
services.setContentResolver(mContext.getContentResolver());
- AccountType readOnlyAccountType = new BaseAccountType();
+ AccountType readOnlyAccountType = new BaseAccountType() {
+ @Override
+ public boolean areContactsWritable() {
+ return false;
+ }
+ };
readOnlyAccountType.accountType = READONLY_ACCOUNT_TYPE;
- readOnlyAccountType.readOnly = true;
- AccountType writableAccountType = new BaseAccountType();
+ AccountType writableAccountType = new BaseAccountType() {
+ @Override
+ public boolean areContactsWritable() {
+ return true;
+ }
+ };
writableAccountType.accountType = WRITABLE_ACCOUNT_TYPE;
services.setSystemService(AccountTypeManager.ACCOUNT_TYPE_SERVICE,
diff --git a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java b/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
index 81c270f..aadf411 100644
--- a/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
+++ b/tests/src/com/android/contacts/model/AccountTypeManagerTest.java
@@ -196,5 +196,10 @@
public boolean isGroupMembershipEditable() {
return false;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return false;
+ }
}
}
diff --git a/tests/src/com/android/contacts/model/AccountTypeTest.java b/tests/src/com/android/contacts/model/AccountTypeTest.java
index 3d80b52..9f7e7a2 100644
--- a/tests/src/com/android/contacts/model/AccountTypeTest.java
+++ b/tests/src/com/android/contacts/model/AccountTypeTest.java
@@ -84,6 +84,10 @@
@Override public boolean isGroupMembershipEditable() {
return false;
}
+
+ @Override public boolean areContactsWritable() {
+ return false;
+ }
};
assertEquals(getTestContext().getString(externalResID),
@@ -137,5 +141,10 @@
public boolean isGroupMembershipEditable() {
return false;
}
+
+ @Override
+ public boolean areContactsWritable() {
+ return false;
+ }
}
}