Merge "Import translations. DO NOT MERGE" into klp-dev
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index d268345..2ec746e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -27,6 +27,7 @@
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
@@ -238,6 +239,12 @@
</intent-filter>
</receiver>
+ <receiver android:name=".interactions.UndemoteOutgoingCallReceiver">
+ <intent-filter>
+ <action android:name="android.intent.action.NEW_OUTGOING_CALL" />
+ </intent-filter>
+ </receiver>
+
<service
android:name=".calllog.CallLogNotificationsService"
android:exported="false"
diff --git a/src/com/android/dialer/DialtactsActivity.java b/src/com/android/dialer/DialtactsActivity.java
index bd2dbf3..499ff31 100644
--- a/src/com/android/dialer/DialtactsActivity.java
+++ b/src/com/android/dialer/DialtactsActivity.java
@@ -737,6 +737,13 @@
* Shows the search fragment
*/
private void enterSearchUi(boolean smartDialSearch, String query) {
+ if (getFragmentManager().isDestroyed()) {
+ // Weird race condition where fragment is doing work after the activity is destroyed
+ // due to talkback being on (b/10209937). Just return since we can't do any
+ // constructive here.
+ return;
+ }
+
if (DEBUG) {
Log.d(TAG, "Entering search UI - smart dial " + smartDialSearch);
}
diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java
index 2c81f46..15c9b05 100644
--- a/src/com/android/dialer/calllog/CallLogAdapter.java
+++ b/src/com/android/dialer/calllog/CallLogAdapter.java
@@ -178,6 +178,10 @@
/** Can be set to true by tests to disable processing of requests. */
private volatile boolean mRequestProcessingDisabled = false;
+ /** True if CallLogAdapter is created from the PhoneFavoriteFragment, where the primary
+ * action should be set to call a number instead of opening the detail page. */
+ private boolean mUseCallAsPrimaryAction = false;
+
/** Listener for the primary action in the list, opens the call details. */
private final View.OnClickListener mPrimaryActionListener = new View.OnClickListener() {
@Override
@@ -228,12 +232,13 @@
};
public CallLogAdapter(Context context, CallFetcher callFetcher,
- ContactInfoHelper contactInfoHelper) {
+ ContactInfoHelper contactInfoHelper, boolean useCallAsPrimaryAction) {
super(context);
mContext = context;
mCallFetcher = callFetcher;
mContactInfoHelper = contactInfoHelper;
+ mUseCallAsPrimaryAction = useCallAsPrimaryAction;
mContactInfoCache = ExpirableCache.create(CONTACT_INFO_CACHE_SIZE);
mRequests = new LinkedList<ContactInfoRequest>();
@@ -515,9 +520,15 @@
final ContactInfo cachedContactInfo = getContactInfoFromCallLog(c);
- views.primaryActionView.setTag(
- IntentProvider.getCallDetailIntentProvider(
- getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
+ if (!mUseCallAsPrimaryAction) {
+ // Sets the primary action to open call detail page.
+ views.primaryActionView.setTag(
+ IntentProvider.getCallDetailIntentProvider(
+ getCursor(), c.getPosition(), c.getLong(CallLogQuery.ID), count));
+ } else {
+ // Sets the primary action to call the number.
+ views.primaryActionView.setTag(IntentProvider.getReturnCallIntentProvider(number));
+ }
// Store away the voicemail information so we can play it directly.
if (callType == Calls.VOICEMAIL_TYPE) {
@@ -594,7 +605,8 @@
final boolean isNew = c.getInt(CallLogQuery.IS_READ) == 0;
// New items also use the highlighted version of the text.
final boolean isHighlighted = isNew;
- mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted);
+ mCallLogViewsHelper.setPhoneCallDetails(views, details, isHighlighted,
+ mUseCallAsPrimaryAction);
setPhoto(views, photoId, lookupUri);
// Listen for the first draw
diff --git a/src/com/android/dialer/calllog/CallLogFragment.java b/src/com/android/dialer/calllog/CallLogFragment.java
index a76d0c1..7168667 100644
--- a/src/com/android/dialer/calllog/CallLogFragment.java
+++ b/src/com/android/dialer/calllog/CallLogFragment.java
@@ -237,7 +237,7 @@
updateEmptyMessage(mCallTypeFilter);
String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
mAdapter = new CallLogAdapter(getActivity(), this,
- new ContactInfoHelper(getActivity(), currentCountryIso));
+ new ContactInfoHelper(getActivity(), currentCountryIso), false);
setListAdapter(mAdapter);
getListView().setItemsCanFocus(true);
}
diff --git a/src/com/android/dialer/calllog/CallLogListItemHelper.java b/src/com/android/dialer/calllog/CallLogListItemHelper.java
index 23366e4..fc26e85 100644
--- a/src/com/android/dialer/calllog/CallLogListItemHelper.java
+++ b/src/com/android/dialer/calllog/CallLogListItemHelper.java
@@ -57,7 +57,7 @@
* @param isHighlighted whether to use the highlight text for the call
*/
public void setPhoneCallDetails(CallLogListItemViews views, PhoneCallDetails details,
- boolean isHighlighted) {
+ boolean isHighlighted, boolean useCallAsPrimaryAction) {
mPhoneCallDetailsHelper.setPhoneCallDetails(views.phoneCallDetailsViews, details,
isHighlighted);
boolean canCall = PhoneNumberHelper.canPlaceCallsTo(details.number,
@@ -67,7 +67,7 @@
if (canPlay) {
// Playback action takes preference.
configurePlaySecondaryAction(views, isHighlighted);
- } else if (canCall) {
+ } else if (canCall && !useCallAsPrimaryAction) {
// Call is the secondary action.
configureCallSecondaryAction(views, details);
} else {
diff --git a/src/com/android/dialer/interactions/PhoneNumberInteraction.java b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
index 8c64c5f..722b9b3 100644
--- a/src/com/android/dialer/interactions/PhoneNumberInteraction.java
+++ b/src/com/android/dialer/interactions/PhoneNumberInteraction.java
@@ -309,15 +309,6 @@
}
private void performAction(String phoneNumber) {
- if (mInteractionType == ContactDisplayUtils.INTERACTION_CALL && mContactId !=
- UNKNOWN_CONTACT_ID) {
- // Since we are making an outgoing call to this contact, undemote it here.
- // If the contact is not demoted, this will not do anything.
- final ContentValues cv = new ContentValues(1);
- cv.put(String.valueOf(mContactId), PinnedPositions.UNDEMOTE);
- mContext.getContentResolver().update(PinnedPositions.UPDATE_URI, cv, null, null);
- }
-
PhoneNumberInteraction.performAction(mContext, phoneNumber, mInteractionType, mCallOrigin);
}
diff --git a/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
new file mode 100644
index 0000000..8782ce4
--- /dev/null
+++ b/src/com/android/dialer/interactions/UndemoteOutgoingCallReceiver.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2013 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.dialer.interactions;
+
+import android.content.BroadcastReceiver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.provider.ContactsContract.PhoneLookup;
+import android.provider.ContactsContract.PinnedPositions;
+
+/**
+ * This broadcast receiver is used to listen to outgoing calls and undemote formerly demoted
+ * contacts if a phone call is made to a phone number belonging to that contact.
+ */
+public class UndemoteOutgoingCallReceiver extends BroadcastReceiver {
+
+ private static final long NO_CONTACT_FOUND = -1;
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (intent != null && Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
+ final String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
+ final long id = getContactIdFromPhoneNumber(context, number);
+ if (id != NO_CONTACT_FOUND) {
+ undemoteContactWithId(context, id);
+ }
+ }
+ }
+
+ private void undemoteContactWithId(Context context, long id) {
+ final ContentValues cv = new ContentValues(1);
+ cv.put(String.valueOf(id), PinnedPositions.UNDEMOTE);
+ // If the contact is not demoted, this will not do anything. Otherwise, it will
+ // restore it to an unpinned position. If it was a frequently called contact, it will
+ // show up once again show up on the favorites screen.
+ context.getContentResolver().update(PinnedPositions.UPDATE_URI, cv, null, null);
+ }
+
+ private long getContactIdFromPhoneNumber(Context context, String number) {
+ final Uri contactUri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI,
+ Uri.encode(number));
+ final Cursor cursor = context.getContentResolver().query(contactUri, new String[] {
+ PhoneLookup._ID}, null, null, null);
+ try {
+ if (cursor.moveToFirst()) {
+ final long id = cursor.getLong(0);
+ return id;
+ } else {
+ return NO_CONTACT_FOUND;
+ }
+ } finally {
+ cursor.close();
+ }
+ }
+}
diff --git a/src/com/android/dialer/list/PhoneFavoriteFragment.java b/src/com/android/dialer/list/PhoneFavoriteFragment.java
index a1406d2..8759779 100644
--- a/src/com/android/dialer/list/PhoneFavoriteFragment.java
+++ b/src/com/android/dialer/list/PhoneFavoriteFragment.java
@@ -182,7 +182,7 @@
this, 1);
final String currentCountryIso = GeoUtil.getCurrentCountryIso(getActivity());
mCallLogAdapter = new CallLogAdapter(getActivity(), this,
- new ContactInfoHelper(getActivity(), currentCountryIso));
+ new ContactInfoHelper(getActivity(), currentCountryIso), true);
setHasOptionsMenu(true);
}
diff --git a/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java b/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java
index 6d9fdcb..14c1043 100644
--- a/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteRegularRowView.java
@@ -16,6 +16,7 @@
package com.android.dialer.list;
import android.content.Context;
+import android.content.res.Resources;
import android.util.AttributeSet;
import android.view.GestureDetector;
@@ -40,6 +41,25 @@
super.onFinishInflate();
mFavoriteContactCard = findViewById(R.id.contact_favorite_card);
+
+ final int rowPaddingStart;
+ final int rowPaddingEnd;
+ final int rowPaddingTop;
+ final int rowPaddingBottom;
+
+ final Resources resources = getResources();
+ rowPaddingStart = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_start_padding);
+ rowPaddingEnd = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_end_padding);
+ rowPaddingTop = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_top_padding);
+ rowPaddingBottom = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_bottom_padding);
+
+ mFavoriteContactCard.setPaddingRelative(rowPaddingStart, rowPaddingTop, rowPaddingEnd,
+ rowPaddingBottom);
+
mRemovalDialogue = findViewById(R.id.favorite_remove_dialogue);
mUndoRemovalButton = findViewById(R.id.favorite_remove_undo_button);
diff --git a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
index fe07d18..6c1542d 100644
--- a/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
+++ b/src/com/android/dialer/list/PhoneFavoriteSquareTileView.java
@@ -18,6 +18,7 @@
import android.content.Context;
import android.content.Intent;
+import android.provider.ContactsContract.QuickContact;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.View;
@@ -51,11 +52,7 @@
mSecondaryButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- Intent intent = new Intent(Intent.ACTION_VIEW, getLookupUri());
- // Secondary target will be visible only from phone's favorite screen, then
- // we want to launch it as a separate People task.
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
- getContext().startActivity(intent);
+ launchQuickContact();
}
});
@@ -79,4 +76,9 @@
// The picture is the full size of the tile (minus some padding, but we can be generous)
return mListener.getApproximateTileWidth();
}
+
+ private void launchQuickContact() {
+ QuickContact.showQuickContact(getContext(), PhoneFavoriteSquareTileView.this,
+ getLookupUri(), QuickContact.MODE_LARGE, null);
+ }
}
diff --git a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
index 3aa85e8..b4e00fb 100644
--- a/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
+++ b/src/com/android/dialer/list/PhoneFavoritesTileAdapter.java
@@ -652,14 +652,26 @@
mPosition = position;
final Resources resources = mContext.getResources();
- mRowPaddingStart = resources.getDimensionPixelSize(
- R.dimen.favorites_row_start_padding);
- mRowPaddingEnd = resources.getDimensionPixelSize(
- R.dimen.favorites_row_end_padding);
- mRowPaddingTop = resources.getDimensionPixelSize(
- R.dimen.favorites_row_top_padding);
- mRowPaddingBottom = resources.getDimensionPixelSize(
- R.dimen.favorites_row_bottom_padding);
+
+ if (mItemViewType == ViewTypes.TOP) {
+ // For tiled views, we still want padding to be set on the ContactTileRow.
+ // Otherwise the padding would be set around each of the tiles, which we don't want
+ mRowPaddingTop = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_top_padding);
+ mRowPaddingBottom = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_bottom_padding);
+ mRowPaddingStart = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_start_padding);
+ mRowPaddingEnd = resources.getDimensionPixelSize(
+ R.dimen.favorites_row_end_padding);
+
+ } else {
+ // For row views, padding is set on the view itself.
+ mRowPaddingTop = 0;
+ mRowPaddingBottom = 0;
+ mRowPaddingStart = 0;
+ mRowPaddingEnd = 0;
+ }
setBackgroundResource(R.drawable.bottom_border_background);
diff --git a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
index 6811371..ce862de 100644
--- a/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogAdapterTest.java
@@ -212,7 +212,7 @@
public TestCallLogAdapter(Context context, CallFetcher callFetcher,
ContactInfoHelper contactInfoHelper) {
- super(context, callFetcher, contactInfoHelper);
+ super(context, callFetcher, contactInfoHelper, false);
}
@Override
diff --git a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
index 2cc7423..1b793bc 100644
--- a/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
+++ b/tests/src/com/android/dialer/calllog/CallLogListItemHelperTest.java
@@ -77,21 +77,42 @@
assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
}
+ public void testSetPhoneCallDetailsInFavorites() {
+ setPhoneCallDetailsWithNumberInFavorites("12125551234", Calls.PRESENTATION_ALLOWED,
+ "1-212-555-1234");
+ assertNoCallButton();
+ }
+
public void testSetPhoneCallDetails_Unknown() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_UNKNOWN, "");
assertNoCallButton();
}
+ public void testSetPhoneCallDetailsInFavorites_Unknown() {
+ setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_UNKNOWN, "");
+ assertNoCallButton();
+ }
+
public void testSetPhoneCallDetails_Private() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_RESTRICTED, "");
assertNoCallButton();
}
+ public void testSetPhoneCallDetailsInFavorites_Private() {
+ setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_RESTRICTED, "");
+ assertNoCallButton();
+ }
+
public void testSetPhoneCallDetails_Payphone() {
setPhoneCallDetailsWithNumber("", Calls.PRESENTATION_PAYPHONE, "");
assertNoCallButton();
}
+ public void testSetPhoneCallDetailsInFavorites_Payphone() {
+ setPhoneCallDetailsWithNumberInFavorites("", Calls.PRESENTATION_PAYPHONE, "");
+ assertNoCallButton();
+ }
+
public void testSetPhoneCallDetails_VoicemailNumber() {
setPhoneCallDetailsWithNumber(TEST_VOICEMAIL_NUMBER,
Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
@@ -114,6 +135,28 @@
assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
}
+ public void testSetPhoneCallDetailsInFavorites_VoicemailNumber() {
+ setPhoneCallDetailsWithNumberInFavorites(TEST_VOICEMAIL_NUMBER,
+ Calls.PRESENTATION_ALLOWED, TEST_VOICEMAIL_NUMBER);
+ assertNoCallButton();
+ }
+
+ public void testSetPhoneCallDetailsInFavorites_ReadVoicemail() {
+ setPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
+ assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ }
+
+ public void testSetPhoneCallDetailsInFavorites_UnreadVoicemail() {
+ setUnreadPhoneCallDetailsWithTypesInFavorites(Calls.VOICEMAIL_TYPE);
+ assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ }
+
+ public void testSetPhoneCallDetailsInFavorites_VoicemailFromUnknown() {
+ setPhoneCallDetailsWithNumberAndTypeInFavorites("", Calls.PRESENTATION_UNKNOWN,
+ "", Calls.VOICEMAIL_TYPE);
+ assertEquals(View.VISIBLE, mViews.secondaryActionView.getVisibility());
+ }
+
/** Asserts that the whole call area is gone. */
private void assertNoCallButton() {
assertEquals(View.GONE, mViews.secondaryActionView.getVisibility());
@@ -126,6 +169,13 @@
formattedNumber, Calls.INCOMING_TYPE);
}
+ /** Sets the details of a phone call in the favorite screen using the specified phone number. */
+ private void setPhoneCallDetailsWithNumberInFavorites(String number,
+ int presentation, String formattedNumber) {
+ setPhoneCallDetailsWithNumberAndTypeInFavorites(number, presentation,
+ formattedNumber, Calls.INCOMING_TYPE);
+ }
+
/** Sets the details of a phone call using the specified phone number. */
private void setPhoneCallDetailsWithNumberAndType(String number,
int presentation, String formattedNumber, int callType) {
@@ -133,7 +183,17 @@
new PhoneCallDetails(number, presentation, formattedNumber,
TEST_COUNTRY_ISO, TEST_GEOCODE,
new int[]{ callType }, TEST_DATE, TEST_DURATION),
- false);
+ false, false);
+ }
+
+ /** Sets the details of a phone call in the favorite screen using the specified phone number. */
+ private void setPhoneCallDetailsWithNumberAndTypeInFavorites(String number,
+ int presentation, String formattedNumber, int callType) {
+ mHelper.setPhoneCallDetails(mViews,
+ new PhoneCallDetails(number, presentation, formattedNumber,
+ TEST_COUNTRY_ISO, TEST_GEOCODE,
+ new int[]{ callType }, TEST_DATE, TEST_DURATION),
+ false, true);
}
/** Sets the details of a phone call using the specified call type. */
@@ -142,15 +202,35 @@
new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
types, TEST_DATE, TEST_DURATION),
- false);
+ false, false);
}
- /** Sets the details of a phone call using the specified call type. */
+ /** Sets the details of a phone call in the favorite screen using the specified call type. */
+ private void setPhoneCallDetailsWithTypesInFavorites(int... types) {
+ mHelper.setPhoneCallDetails(mViews,
+ new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
+ types, TEST_DATE, TEST_DURATION),
+ false, true);
+ }
+
+ /** Sets the details of an unread phone call using the specified call type. */
private void setUnreadPhoneCallDetailsWithTypes(int... types) {
mHelper.setPhoneCallDetails(mViews,
new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
types, TEST_DATE, TEST_DURATION),
- true);
+ true, false);
+ }
+
+ /** Sets the details of an unread phone call in the favorite screen using the specified call
+ * type.
+ */
+ private void setUnreadPhoneCallDetailsWithTypesInFavorites(int... types) {
+ mHelper.setPhoneCallDetails(mViews,
+ new PhoneCallDetails(TEST_NUMBER, Calls.PRESENTATION_ALLOWED,
+ TEST_FORMATTED_NUMBER, TEST_COUNTRY_ISO, TEST_GEOCODE,
+ types, TEST_DATE, TEST_DURATION),
+ true, true);
}
}