summaryrefslogtreecommitdiff
path: root/java/com/android/dialer/voicemail
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2018-01-26 01:25:27 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2018-01-26 01:25:27 +0000
commit328494b2e757dce8e385879303a1c2eb0364c635 (patch)
tree7ed3bed3f0ca69e0e98462140363d6fb52776c7a /java/com/android/dialer/voicemail
parent2684d0b9a258171cfc35c17bce7f6d23cead3172 (diff)
parentc5b58aa372390b544668c79550c70237399c8c0d (diff)
Merge "Show voicemail error messages for NUI"
Diffstat (limited to 'java/com/android/dialer/voicemail')
-rw-r--r--java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java164
-rw-r--r--java/com/android/dialer/voicemail/listui/NewVoicemailAlertViewHolder.java32
-rw-r--r--java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java29
-rw-r--r--java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_entry_alert.xml101
-rw-r--r--java/com/android/dialer/voicemail/listui/res/values/dimens.xml9
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>