diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2018-01-26 01:25:27 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2018-01-26 01:25:27 +0000 |
commit | 328494b2e757dce8e385879303a1c2eb0364c635 (patch) | |
tree | 7ed3bed3f0ca69e0e98462140363d6fb52776c7a | |
parent | 2684d0b9a258171cfc35c17bce7f6d23cead3172 (diff) | |
parent | c5b58aa372390b544668c79550c70237399c8c0d (diff) |
Merge "Show voicemail error messages for NUI"
5 files changed, 281 insertions, 54 deletions
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java index 5519aa486..318f79783 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java @@ -25,6 +25,7 @@ import android.media.MediaPlayer.OnPreparedListener; import android.net.Uri; import android.support.annotation.IntDef; import android.support.annotation.Nullable; +import android.support.annotation.VisibleForTesting; import android.support.annotation.WorkerThread; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView.ViewHolder; @@ -43,9 +44,15 @@ import com.android.dialer.common.concurrent.DialerExecutorComponent; import com.android.dialer.common.concurrent.ThreadUtil; import com.android.dialer.time.Clock; import com.android.dialer.voicemail.listui.NewVoicemailViewHolder.NewVoicemailViewHolderListener; +import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage; +import com.android.dialer.voicemail.listui.error.VoicemailErrorMessageCreator; +import com.android.dialer.voicemail.listui.error.VoicemailStatus; import com.android.dialer.voicemail.model.VoicemailEntry; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; import java.util.Objects; import java.util.Set; @@ -66,6 +73,7 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> } private Cursor cursor; + private Cursor voicemailStatusCursor; private final Clock clock; /** {@link Integer#MAX_VALUE} when the "Today" header should not be displayed. */ @@ -81,6 +89,8 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> /** A valid id for {@link VoicemailEntry} is greater than 0 */ private int currentlyExpandedViewHolderId = -1; + private VoicemailErrorMessage voicemailErrorMessage; + /** * It takes time to delete voicemails from the server, so we "remove" them and remember the * positions we removed until a new cursor is ready. @@ -248,34 +258,14 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> if (viewHolder instanceof NewVoicemailHeaderViewHolder) { LogUtil.i( "NewVoicemailAdapter.onBindViewHolder", "view holder at pos:%d is a header", position); - NewVoicemailHeaderViewHolder headerViewHolder = (NewVoicemailHeaderViewHolder) viewHolder; - @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 { - throw Assert.createIllegalStateFailException( - "Unexpected view type " + viewType + " at position: " + position); - } + onBindHeaderViewHolder(viewHolder, position); return; } if (viewHolder instanceof NewVoicemailAlertViewHolder) { LogUtil.i( "NewVoicemailAdapter.onBindViewHolder", "view holder at pos:%d is a alert", position); - NewVoicemailAlertViewHolder alertViewHolder = (NewVoicemailAlertViewHolder) viewHolder; - @RowType int viewType = getItemViewType(position); - Assert.checkArgument(position == 0); - if (position == voicemailAlertPosition) { - // TODO(a bug): Update this with the alert messages - alertViewHolder.setHeader("Temporary placeholder, update this with the alert messages"); - } else { - throw Assert.createIllegalStateFailException( - "Unexpected view type " + viewType + " at position: " + position); - } + onBindAlertViewHolder(viewHolder, position); return; } @@ -285,26 +275,13 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> position); NewVoicemailViewHolder newVoicemailViewHolder = (NewVoicemailViewHolder) viewHolder; - - int previousHeaders = 0; - if (voicemailAlertPosition != Integer.MAX_VALUE && position > voicemailAlertPosition) { - previousHeaders++; - } - if (todayHeaderPosition != Integer.MAX_VALUE && position > todayHeaderPosition) { - previousHeaders++; - } - if (yesterdayHeaderPosition != Integer.MAX_VALUE && position > yesterdayHeaderPosition) { - previousHeaders++; - } - if (olderHeaderPosition != Integer.MAX_VALUE && position > olderHeaderPosition) { - previousHeaders++; - } + int nonVoicemailEntryHeaders = getHeaderCountAtPosition(position); LogUtil.i( "NewVoicemailAdapter.onBindViewHolder", - "view holder at pos:%d, prevHeaderCount:%d", + "view holder at pos:%d, nonVoicemailEntryHeaders:%d", position, - previousHeaders); + nonVoicemailEntryHeaders); // Remove if the viewholder is being recycled. if (newVoicemailViewHolderArrayMap.containsKey(newVoicemailViewHolder.getViewHolderId())) { @@ -322,7 +299,7 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> } newVoicemailViewHolder.reset(); - cursor.moveToPosition(position - previousHeaders); + cursor.moveToPosition(position - nonVoicemailEntryHeaders); newVoicemailViewHolder.bindViewHolderValuesFromAdapter( cursor, fragmentManager, mediaPlayer, position, currentlyExpandedViewHolderId); @@ -378,6 +355,72 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> printArrayMap(); } + private int getHeaderCountAtPosition(int position) { + int previousHeaders = 0; + if (voicemailAlertPosition != Integer.MAX_VALUE && position > voicemailAlertPosition) { + previousHeaders++; + } + if (todayHeaderPosition != Integer.MAX_VALUE && position > todayHeaderPosition) { + previousHeaders++; + } + if (yesterdayHeaderPosition != Integer.MAX_VALUE && position > yesterdayHeaderPosition) { + previousHeaders++; + } + if (olderHeaderPosition != Integer.MAX_VALUE && position > olderHeaderPosition) { + previousHeaders++; + } + return previousHeaders; + } + + private void onBindAlertViewHolder(ViewHolder viewHolder, int position) { + LogUtil.i( + "NewVoicemailAdapter.onBindAlertViewHolder", + "pos:%d, voicemailAlertPosition:%d", + position, + voicemailAlertPosition); + + NewVoicemailAlertViewHolder alertViewHolder = (NewVoicemailAlertViewHolder) viewHolder; + @RowType int viewType = getItemViewType(position); + + Assert.checkArgument(position == 0, "position is not 0"); + Assert.checkArgument( + position == voicemailAlertPosition, + String.format( + Locale.US, + "position:%d and voicemailAlertPosition:%d are different", + position, + voicemailAlertPosition)); + Assert.checkArgument(viewType == RowType.VOICEMAIL_ALERT, "Invalid row type: " + viewType); + Assert.checkArgument( + voicemailErrorMessage.getActions().size() <= 2, + "Too many actions: " + voicemailErrorMessage.getActions().size()); + + alertViewHolder.setTitle(voicemailErrorMessage.getTitle()); + alertViewHolder.setDescription(voicemailErrorMessage.getDescription()); + + if (!voicemailErrorMessage.getActions().isEmpty()) { + alertViewHolder.setPrimaryButton(voicemailErrorMessage.getActions().get(0)); + } + if (voicemailErrorMessage.getActions().size() > 1) { + alertViewHolder.setSecondaryButton(voicemailErrorMessage.getActions().get(1)); + } + } + + private void onBindHeaderViewHolder(ViewHolder viewHolder, int position) { + NewVoicemailHeaderViewHolder headerViewHolder = (NewVoicemailHeaderViewHolder) viewHolder; + @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 { + throw Assert.createIllegalStateFailException( + "Unexpected view type " + viewType + " at position: " + position); + } + } + private void printArrayMap() { LogUtil.i( "NewVoicemailAdapter.printArrayMap", @@ -958,4 +1001,47 @@ final class NewVoicemailAdapter extends RecyclerView.Adapter<ViewHolder> LogUtil.i("NewVoicemailAdapter.checkAndPlayVoicemail", "not playing downloaded voicemail"); } } + + @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) + public void setVoicemailStatusCursor(Cursor voicemailStatusCursor) { + this.voicemailStatusCursor = voicemailStatusCursor; + } + + // TODO(uabdullah): Handle ToS properly + public void updateAlert(Context context) { + if (voicemailStatusCursor == null) { + LogUtil.i("NewVoicemailAdapter.updateAlert", "status cursor was null"); + return; + } + + LogUtil.i( + "NewVoicemailAdapter.updateAlert", + "status cursor size was " + voicemailStatusCursor.getCount()); + + List<VoicemailStatus> statuses = new ArrayList<>(); + + while (voicemailStatusCursor.moveToNext()) { + VoicemailStatus status = new VoicemailStatus(context, voicemailStatusCursor); + if (status.isActive()) { + statuses.add(status); + // TODO(uabdullah): addServiceStateListener + } + } + + voicemailErrorMessage = null; + VoicemailErrorMessageCreator messageCreator = new VoicemailErrorMessageCreator(); + + for (VoicemailStatus status : statuses) { + voicemailErrorMessage = messageCreator.create(context, status, null); + if (voicemailErrorMessage != null) { + break; + } + } + + if (voicemailErrorMessage != null) { + voicemailAlertPosition = 0; + updateHeaderPositions(); + notifyItemChanged(0); + } + } } diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java index ec603b5c8..ac989a8df 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java @@ -18,19 +18,43 @@ package com.android.dialer.voicemail.listui; import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.View; +import android.widget.Button; import android.widget.TextView; +import com.android.dialer.voicemail.listui.error.VoicemailErrorMessage.Action; /** ViewHolder for {@link NewVoicemailAdapter} to display voicemail error states. */ final class NewVoicemailAlertViewHolder extends ViewHolder { - private final TextView errorTextView; + private final TextView voicemailErrorTitleTextView; + private final TextView voicemailErrorDetailsTextView; + private final Button primaryButton; + private final Button secondaryButton; NewVoicemailAlertViewHolder(View view) { super(view); - errorTextView = view.findViewById(R.id.new_voicemail_alert_text); + voicemailErrorTitleTextView = view.findViewById(R.id.voicemail_alert_header); + voicemailErrorDetailsTextView = view.findViewById(R.id.voicemail_alert_details); + primaryButton = view.findViewById(R.id.voicemail_alert_primary_button); + secondaryButton = view.findViewById(R.id.voicemail_alert_primary_button); } - void setHeader(String error) { - errorTextView.setText(error); + void setTitle(CharSequence error) { + voicemailErrorTitleTextView.setText(error); + } + + void setDescription(CharSequence error) { + voicemailErrorDetailsTextView.setText(error); + } + + void setPrimaryButton(Action action) { + primaryButton.setVisibility(View.VISIBLE); + primaryButton.setText(action.getText()); + primaryButton.setOnClickListener(action.getListener()); + } + + void setSecondaryButton(Action action) { + secondaryButton.setVisibility(View.VISIBLE); + secondaryButton.setText(action.getText()); + secondaryButton.setOnClickListener(action.getListener()); } } diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java index b4be42455..0d91f0158 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java @@ -28,11 +28,15 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.android.dialer.common.LogUtil; +import com.android.dialer.database.CallLogQueryHandler; +import com.android.dialer.database.CallLogQueryHandler.Listener; +// TODO(uabdullah): Register content observer for VoicemailContract.Status.CONTENT_URI in onStart /** Fragment for Dialer Voicemail Tab. */ public final class NewVoicemailFragment extends Fragment implements LoaderCallbacks<Cursor> { private RecyclerView recyclerView; + private CallLogQueryHandler callLogQueryHandler; @Nullable @Override @@ -72,6 +76,31 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba ((NewVoicemailAdapter) recyclerView.getAdapter()).updateCursor(data); ((NewVoicemailAdapter) recyclerView.getAdapter()).checkAndPlayVoicemail(); } + callLogQueryHandler = + new CallLogQueryHandler( + getContext(), getContext().getContentResolver(), new NewVoicemailFragmentListener()); + callLogQueryHandler.fetchVoicemailStatus(); + } + + private final class NewVoicemailFragmentListener implements Listener { + + @Override + public void onVoicemailStatusFetched(Cursor statusCursor) { + LogUtil.enterBlock("NewVoicemailFragmentListener.onVoicemailStatusFetched"); + ((NewVoicemailAdapter) recyclerView.getAdapter()).setVoicemailStatusCursor(statusCursor); + ((NewVoicemailAdapter) recyclerView.getAdapter()).updateAlert(getContext()); + } + + @Override + public void onVoicemailUnreadCountFetched(Cursor cursor) {} + + @Override + public void onMissedCallsUnreadCountFetched(Cursor cursor) {} + + @Override + public boolean onCallsFetched(Cursor combinedCursor) { + return false; + } } @Override diff --git a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml index e8dcd02d6..28d639118 100644 --- a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml +++ b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml @@ -14,17 +14,96 @@ ~ See the License for the specific language governing permissions and ~ limitations under the License --> -<RelativeLayout + +<!-- TODO(uabdullah): Use a relative layout instead of nested linear layouts.--> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" - android:height="48dp" + android:id="@+id/voicemail_alert_content" android:layout_width="match_parent" - android:layout_height="wrap_content"> - <!-- TODO(uabdullah): Confirm with UX on mocks --> - <TextView - android:id="@+id/new_voicemail_alert_text" - style="@style/SecondaryText" - android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <LinearLayout + android:layout_width="match_parent" android:layout_height="wrap_content" - android:layout_marginStart="@dimen/voicemail_header_margin_start" - android:layout_centerVertical="true"/> -</RelativeLayout> + android:paddingTop="@dimen/alert_main_padding" + android:paddingBottom="@dimen/alert_main_padding" + android:paddingStart="@dimen/alert_main_padding" + android:paddingEnd="@dimen/alert_main_padding" + android:gravity="top" + android:orientation="horizontal"> + + <ImageView + android:id="@+id/voicemail_alert_icon" + android:layout_width="@dimen/voicemail_promo_card_icon_size" + android:layout_height="@dimen/voicemail_promo_card_icon_size" + android:layout_gravity="top" + android:src="@drawable/ic_voicemail_error_24px"/> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginStart="@dimen/voicemail_promo_card_main_padding" + android:gravity="center_vertical" + android:orientation="vertical"> + + <TextView + android:id="@+id/voicemail_alert_header" + android:textStyle="bold" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginBottom="@dimen/voicemail_promo_card_title_padding" + android:layout_gravity="center_vertical" + android:singleLine="false" + android:text="Voicemail Alert" + android:textSize="@dimen/voicemail_promo_card_title_text_size"/> + + <TextView + android:id="@+id/voicemail_alert_details" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:lineSpacingExtra="@dimen/voicemail_promo_card_line_spacing" + android:singleLine="false" + android:text="This is a voicemail alert message." + android:textSize="@dimen/voicemail_promo_card_message_size"/> + </LinearLayout> + </LinearLayout> + + <LinearLayout + android:id="@+id/voicemail_alert_button" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_gravity="end" + android:paddingTop="10dp" + android:paddingBottom="10dp" + android:paddingStart="16dp" + android:paddingEnd="16dp" + android:gravity="end" + android:minHeight="56dp" + android:orientation="horizontal"> + <Button + android:id="@+id/voicemail_alert_secondary_button" + style="@style/TosButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/dialer_theme_color"/> + + <Button + android:id="@+id/voicemail_alert_primary_button" + style="@style/TosButtonStyle" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textColor="@color/dialer_theme_color"/> + </LinearLayout> + + <LinearLayout + android:layout_width="0dip" + android:layout_height="match_parent" + android:layout_weight="1" + android:layout_gravity="center" + android:divider="?android:dividerHorizontal" + android:gravity="center" + android:orientation="vertical" + android:showDividers="middle"> + </LinearLayout> +</LinearLayout> diff --git a/java/com/android/dialer/voicemail/listui/res/values/dimens.xml b/java/com/android/dialer/voicemail/listui/res/values/dimens.xml index 59da7f288..960d327b2 100644 --- a/java/com/android/dialer/voicemail/listui/res/values/dimens.xml +++ b/java/com/android/dialer/voicemail/listui/res/values/dimens.xml @@ -41,4 +41,13 @@ <dimen name="voicemail_tos_image_size">280dp</dimen> + <!-- Dimensions for voicemail alert --> + <dimen name="alert_main_padding">24dp</dimen> + <dimen name="voicemail_promo_card_icon_size">24dp</dimen> + <dimen name="voicemail_promo_card_main_padding">24dp</dimen> + <dimen name="voicemail_promo_card_title_padding">12dp</dimen> + <dimen name="voicemail_promo_card_title_text_size">16sp</dimen> + <dimen name="voicemail_promo_card_line_spacing">4dp</dimen> + <dimen name="voicemail_promo_card_message_size">14sp</dimen> + </resources> |