From 1f58ac19169a1a39e824ab3ea9826af135720df9 Mon Sep 17 00:00:00 2001 From: uabdullah Date: Wed, 24 Jan 2018 12:11:58 -0800 Subject: Add support for yesterday header in NUI Voicemail Tab Currently NUI only supports today and older, however we also need to support yesterday and be consistent with the call log. Bug: 69858354,72331988 Test: Unit Tests PiperOrigin-RevId: 183121631 Change-Id: Ica75164c28ee60a2f776287eefd7eed5db08e035 --- .../voicemail/listui/NewVoicemailAdapter.java | 90 ++++++++++++++-------- .../dialer/voicemail/listui/res/values/strings.xml | 5 +- 2 files changed, 63 insertions(+), 32 deletions(-) (limited to 'java') diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java index c9bf6e1a8..5519aa486 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java @@ -59,7 +59,7 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter @interface RowType { /** A row representing a voicemail alert. */ int VOICEMAIL_ALERT = 1; - /** Header that displays "Today" or "Older". */ + /** Header that displays "Today", "Yesterday" or "Older". */ int HEADER = 2; /** A row representing a voicemail entry. */ int VOICEMAIL_ENTRY = 3; @@ -70,6 +70,8 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter /** {@link Integer#MAX_VALUE} when the "Today" header should not be displayed. */ private int todayHeaderPosition = Integer.MAX_VALUE; + /** {@link Integer#MAX_VALUE} when the "Yesterday" header should not be displayed. */ + private int yesterdayHeaderPosition = Integer.MAX_VALUE; /** {@link Integer#MAX_VALUE} when the "Older" header should not be displayed. */ private int olderHeaderPosition = Integer.MAX_VALUE; /** {@link Integer#MAX_VALUE} when the voicemail alert message should not be displayed. */ @@ -117,11 +119,44 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter private void updateHeaderPositions() { LogUtil.i( "NewVoicemailAdapter.updateHeaderPositions", - "before updating todayPos:%d, olderPos:%d, alertPos:%d", + "before updating todayPos:%d, yestPos:%d, olderPos:%d, alertPos:%d", todayHeaderPosition, + yesterdayHeaderPosition, olderHeaderPosition, voicemailAlertPosition); + // If there are no rows to display, set all header positions to MAX_VALUE. + if (!cursor.moveToFirst()) { + todayHeaderPosition = Integer.MAX_VALUE; + yesterdayHeaderPosition = Integer.MAX_VALUE; + olderHeaderPosition = Integer.MAX_VALUE; + return; + } + + long currentTimeMillis = clock.currentTimeMillis(); + + int numItemsInToday = 0; + int numItemsInYesterday = 0; + + do { + long timestamp = VoicemailCursorLoader.getTimestamp(cursor); + long dayDifference = CallLogDates.getDayDifference(currentTimeMillis, timestamp); + if (dayDifference == 0) { + numItemsInToday++; + } else if (dayDifference == 1) { + numItemsInYesterday++; + } else { + break; + } + } while (cursor.moveToNext()); + + if (numItemsInToday > 0) { + numItemsInToday++; // including the "Today" header; + } + if (numItemsInYesterday > 0) { + numItemsInYesterday++; // including the "Yesterday" header; + } + int alertOffSet = 0; if (voicemailAlertPosition != Integer.MAX_VALUE) { Assert.checkArgument( @@ -129,37 +164,21 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter alertOffSet = 1; } - // Calculate header adapter positions by reading cursor. - long currentTimeMillis = clock.currentTimeMillis(); - if (cursor.moveToNext()) { - long firstTimestamp = VoicemailCursorLoader.getTimestamp(cursor); - if (CallLogDates.getDayDifference(currentTimeMillis, firstTimestamp) == 0) { - this.todayHeaderPosition = 0 + alertOffSet; - int adapterPosition = - 2 + alertOffSet; // Accounted for the "Alert", "Today" header and first row. - while (cursor.moveToNext()) { - long timestamp = VoicemailCursorLoader.getTimestamp(cursor); - - if (CallLogDates.getDayDifference(currentTimeMillis, timestamp) == 0) { - adapterPosition++; - } else { - this.olderHeaderPosition = adapterPosition; - return; - } - } - this.olderHeaderPosition = Integer.MAX_VALUE; // Didn't find any "Older" rows. - } else { - this.todayHeaderPosition = Integer.MAX_VALUE; // Didn't find any "Today" rows. - this.olderHeaderPosition = 0 + alertOffSet; - } - } else { // There are no rows, just need to set these because they are final. - this.todayHeaderPosition = Integer.MAX_VALUE; - this.olderHeaderPosition = Integer.MAX_VALUE; - } + // Set all header positions. + // A header position will be MAX_VALUE if there is no item to be displayed under that header. + todayHeaderPosition = numItemsInToday > 0 ? alertOffSet : Integer.MAX_VALUE; + yesterdayHeaderPosition = + numItemsInYesterday > 0 ? numItemsInToday + alertOffSet : Integer.MAX_VALUE; + olderHeaderPosition = + !cursor.isAfterLast() + ? numItemsInToday + numItemsInYesterday + alertOffSet + : Integer.MAX_VALUE; + LogUtil.i( "NewVoicemailAdapter.updateHeaderPositions", - "after updating todayPos:%d, olderPos:%d, alertOffSet:%d, alertPos:%d", + "after updating todayPos:%d, yestPos:%d, olderPos:%d, alertOffSet:%d, alertPos:%d", todayHeaderPosition, + yesterdayHeaderPosition, olderHeaderPosition, alertOffSet, voicemailAlertPosition); @@ -233,6 +252,8 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter @RowType int viewType = getItemViewType(position); if (position == todayHeaderPosition) { headerViewHolder.setHeader(R.string.new_voicemail_header_today); + } else if (position == yesterdayHeaderPosition) { + headerViewHolder.setHeader(R.string.new_voicemail_header_yesterday); } else if (position == olderHeaderPosition) { headerViewHolder.setHeader(R.string.new_voicemail_header_older); } else { @@ -272,6 +293,9 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter if (todayHeaderPosition != Integer.MAX_VALUE && position > todayHeaderPosition) { previousHeaders++; } + if (yesterdayHeaderPosition != Integer.MAX_VALUE && position > yesterdayHeaderPosition) { + previousHeaders++; + } if (olderHeaderPosition != Integer.MAX_VALUE && position > olderHeaderPosition) { previousHeaders++; } @@ -870,6 +894,9 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter if (todayHeaderPosition != Integer.MAX_VALUE) { numberOfHeaders++; } + if (yesterdayHeaderPosition != Integer.MAX_VALUE) { + numberOfHeaders++; + } if (olderHeaderPosition != Integer.MAX_VALUE) { numberOfHeaders++; } @@ -893,6 +920,9 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter if (todayHeaderPosition != Integer.MAX_VALUE && position == todayHeaderPosition) { return RowType.HEADER; } + if (yesterdayHeaderPosition != Integer.MAX_VALUE && position == yesterdayHeaderPosition) { + return RowType.HEADER; + } if (olderHeaderPosition != Integer.MAX_VALUE && position == olderHeaderPosition) { return RowType.HEADER; } diff --git a/java/com/android/dialer/voicemail/listui/res/values/strings.xml b/java/com/android/dialer/voicemail/listui/res/values/strings.xml index 70a5d03df..e7373d69f 100644 --- a/java/com/android/dialer/voicemail/listui/res/values/strings.xml +++ b/java/com/android/dialer/voicemail/listui/res/values/strings.xml @@ -30,8 +30,9 @@ Today - - + + Yesterday + Older Turn on visual voicemail -- cgit v1.2.3 From a584bcd04d287e7771b0420156a1892a7962e4ff Mon Sep 17 00:00:00 2001 From: calderwoodra Date: Wed, 24 Jan 2018 12:19:56 -0800 Subject: Fixed a regression where we incorrectly reported that the dialpad was visible. A request was made to update the value of #isDialpadVisible, in the process a regression was introduced that would cause #isDialpadVisible to return true when the dialpad's root view was null. This caused a NPE when we tried to animate it. We should now return the correct value in the scenarios important to our partners as well our users and animations. Bug: 64657832,72384544 Test: manual/logging PiperOrigin-RevId: 183122628 Change-Id: I981e944dbb003064163b8ec11883dbc5381cba0e --- java/com/android/incallui/InCallActivity.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'java') diff --git a/java/com/android/incallui/InCallActivity.java b/java/com/android/incallui/InCallActivity.java index 990560674..535b894f6 100644 --- a/java/com/android/incallui/InCallActivity.java +++ b/java/com/android/incallui/InCallActivity.java @@ -822,7 +822,11 @@ public class InCallActivity extends TransactionSafeFragmentActivity public boolean isDialpadVisible() { DialpadFragment dialpadFragment = getDialpadFragment(); - return dialpadFragment != null && dialpadFragment.getUserVisibleHint(); + return dialpadFragment != null + && dialpadFragment.isAdded() + && !dialpadFragment.isHidden() + && dialpadFragment.getView() != null + && dialpadFragment.getUserVisibleHint(); } /** Returns the {@link DialpadFragment} that's shown by this activity, or {@code null} */ -- cgit v1.2.3 From 571a2b4b21116b85b7ce3198ed9ff438a80b380c Mon Sep 17 00:00:00 2001 From: roldenburg Date: Wed, 24 Jan 2018 12:47:44 -0800 Subject: Add foreground service permission Bug: 72116995 Test: built APK, verified permission PiperOrigin-RevId: 183126225 Change-Id: I0889ea619a21413e510a7b58143c5011ed81b688 --- java/com/android/incallui/AndroidManifest.xml | 3 +++ 1 file changed, 3 insertions(+) (limited to 'java') diff --git a/java/com/android/incallui/AndroidManifest.xml b/java/com/android/incallui/AndroidManifest.xml index a98cc91d2..3d5aa1ceb 100644 --- a/java/com/android/incallui/AndroidManifest.xml +++ b/java/com/android/incallui/AndroidManifest.xml @@ -28,6 +28,9 @@ reset state of the app. --> + + + Date: Wed, 24 Jan 2018 13:47:08 -0800 Subject: Link to the correct Assisted Dialing settings depending on platform version. Bug: 72162646 Test: unit tests PiperOrigin-RevId: 183134859 Change-Id: I73d3349f0ff33188cfe0a121b7737a57155683c7 --- java/com/android/dialer/calldetails/CallDetailsActivity.java | 12 ++++++++++-- .../dialer/compat/telephony/TelephonyManagerCompat.java | 4 ++++ 2 files changed, 14 insertions(+), 2 deletions(-) (limited to 'java') diff --git a/java/com/android/dialer/calldetails/CallDetailsActivity.java b/java/com/android/dialer/calldetails/CallDetailsActivity.java index b15dc456d..bf978ecf3 100644 --- a/java/com/android/dialer/calldetails/CallDetailsActivity.java +++ b/java/com/android/dialer/calldetails/CallDetailsActivity.java @@ -32,6 +32,7 @@ import android.provider.CallLog.Calls; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; +import android.support.v4.os.BuildCompat; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -52,6 +53,7 @@ import com.android.dialer.common.concurrent.DialerExecutor.FailureListener; import com.android.dialer.common.concurrent.DialerExecutor.SuccessListener; import com.android.dialer.common.concurrent.DialerExecutor.Worker; import com.android.dialer.common.concurrent.DialerExecutorComponent; +import com.android.dialer.compat.telephony.TelephonyManagerCompat; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.dialercontact.DialerContact; import com.android.dialer.duo.Duo; @@ -407,8 +409,14 @@ public class CallDetailsActivity extends AppCompatActivity { @Override public void openAssistedDialingSettings(View unused) { - Intent intent = new Intent(getActivity(), AssistedDialingSettingActivity.class); - getActivity().startActivity(intent); + if (BuildCompat.isAtLeastP()) { + Intent callSettingsIntent = + new Intent(TelephonyManagerCompat.ACTION_SHOW_ASSISTED_DIALING_SETTINGS); + getActivity().startActivity(callSettingsIntent); + } else { + Intent intent = new Intent(getActivity(), AssistedDialingSettingActivity.class); + getActivity().startActivity(intent); + } } @Override diff --git a/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java b/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java index 86f344f4e..669cba7a9 100644 --- a/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java +++ b/java/com/android/dialer/compat/telephony/TelephonyManagerCompat.java @@ -80,6 +80,10 @@ public class TelephonyManagerCompat { */ public static final Integer FEATURES_ASSISTED_DIALING = 1 << 4; + /** The {@link android.content.Intent} action used to show the assisted dialing settings. */ + public static final String ACTION_SHOW_ASSISTED_DIALING_SETTINGS = + "android.telecom.action.SHOW_ASSISTED_DIALING_SETTINGS"; + /** * Returns the number of phones available. Returns 1 for Single standby mode (Single SIM * functionality) Returns 2 for Dual standby mode.(Dual SIM functionality) -- cgit v1.2.3 From 9e04310a9902a4dbf593060baaf41c37919fd7fe Mon Sep 17 00:00:00 2001 From: linyuh Date: Wed, 24 Jan 2018 14:07:05 -0800 Subject: Define methods in Spam interface to be used later in the PhoneLookup for spam features. Bug: 70989534 Test: ApdlSpamTest, InAppSpamTest PiperOrigin-RevId: 183138320 Change-Id: I647568c31e234995f44d6cbeb2f97f73952db6bb --- java/com/android/dialer/spam/Spam.java | 25 ++++++++++++++++++++++- java/com/android/dialer/spam/SpamStub.java | 32 +++++++++++++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) (limited to 'java') diff --git a/java/com/android/dialer/spam/Spam.java b/java/com/android/dialer/spam/Spam.java index b1240c69a..ea1ea138e 100644 --- a/java/com/android/dialer/spam/Spam.java +++ b/java/com/android/dialer/spam/Spam.java @@ -18,9 +18,13 @@ package com.android.dialer.spam; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import com.android.dialer.DialerPhoneNumber; import com.android.dialer.logging.ContactLookupResult; import com.android.dialer.logging.ContactSource; import com.android.dialer.logging.ReportingLocation; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.ListenableFuture; /** Allows the container application to mark calls as spam. */ public interface Spam { @@ -39,7 +43,17 @@ public interface Spam { int percentOfNonSpamNotificationsToShow(); /** - * Checks if the given number is suspected of being a spamer. + * Checks if each of numbers in the given list is suspected of being a spam. + * + * @param dialerPhoneNumbers A list of {@link DialerPhoneNumber}. + * @return A {@link ListenableFuture} of a map that maps each number to its spam status + * (true/false). + */ + ListenableFuture> batchCheckSpamStatus( + ImmutableList dialerPhoneNumbers); + + /** + * Checks if the given number is suspected of being a spam. * * @param number The phone number of the call. * @param countryIso The country ISO of the call. @@ -80,6 +94,15 @@ public interface Spam { */ boolean checkSpamStatusSynchronous(String number, String countryIso); + /** + * Returns a {@link ListenableFuture} indicating whether the spam data have been updated since + * {@code timestampMillis}. + * + *

It is the caller's responsibility to ensure the timestamp is in milliseconds. Failure to do + * so will result in undefined behavior. + */ + ListenableFuture dataUpdatedSince(long timestampMillis); + /** * Reports number as spam. * diff --git a/java/com/android/dialer/spam/SpamStub.java b/java/com/android/dialer/spam/SpamStub.java index daa475c4a..ac2e94359 100644 --- a/java/com/android/dialer/spam/SpamStub.java +++ b/java/com/android/dialer/spam/SpamStub.java @@ -16,16 +16,27 @@ package com.android.dialer.spam; +import com.android.dialer.DialerPhoneNumber; +import com.android.dialer.common.concurrent.Annotations.BackgroundExecutor; import com.android.dialer.logging.ContactLookupResult; import com.android.dialer.logging.ContactSource; import com.android.dialer.logging.ReportingLocation; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; +import com.google.common.util.concurrent.ListeningExecutorService; import javax.inject.Inject; /** Default implementation of Spam. */ public class SpamStub implements Spam { + private final ListeningExecutorService backgroundExecutorService; + @Inject - public SpamStub() {} + public SpamStub(@BackgroundExecutor ListeningExecutorService backgroundExecutorService) { + this.backgroundExecutorService = backgroundExecutorService; + } @Override public boolean isSpamEnabled() { @@ -57,6 +68,20 @@ public class SpamStub implements Spam { return 0; } + @Override + public ListenableFuture> batchCheckSpamStatus( + ImmutableList dialerPhoneNumbers) { + return backgroundExecutorService.submit( + () -> { + ImmutableMap.Builder resultBuilder = + new ImmutableMap.Builder<>(); + for (DialerPhoneNumber dialerPhoneNumber : dialerPhoneNumbers) { + resultBuilder.put(dialerPhoneNumber, false); + } + return resultBuilder.build(); + }); + } + @Override public void checkSpamStatus(String number, String countryIso, Listener listener) { listener.onComplete(false); @@ -82,6 +107,11 @@ public class SpamStub implements Spam { return false; } + @Override + public ListenableFuture dataUpdatedSince(long timestampMillis) { + return Futures.immediateFuture(false); + } + @Override public void reportSpamFromAfterCallNotification( String number, -- cgit v1.2.3