From bdd2bc2efe22dc5b14cd2d3f5eb20350b69da875 Mon Sep 17 00:00:00 2001 From: Nancy Chen Date: Mon, 22 Jun 2015 21:45:03 -0700 Subject: Add a promo card for visual voicemail. The promo card explains what visual voicemail is, along with a link to settings to disable it and an ok button to dismiss it. Also move common resources from GoogleDialer to the respective resource files. Bug: 21086059 Change-Id: Iecfe778b815fb572667d0cecdb958205ec1b48a0 --- res/layout/voicemail_promo_card.xml | 99 ++++++++++++++ res/values/colors.xml | 5 + res/values/dimens.xml | 11 ++ res/values/styles.xml | 14 ++ src/com/android/dialer/calllog/CallLogAdapter.java | 146 +++++++++++++++++++-- .../dialer/calllog/PromoCardViewHolder.java | 71 ++++++++++ 6 files changed, 338 insertions(+), 8 deletions(-) create mode 100644 res/layout/voicemail_promo_card.xml create mode 100644 src/com/android/dialer/calllog/PromoCardViewHolder.java diff --git a/res/layout/voicemail_promo_card.xml b/res/layout/voicemail_promo_card.xml new file mode 100644 index 000000000..103fa30b3 --- /dev/null +++ b/res/layout/voicemail_promo_card.xml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/values/colors.xml b/res/values/colors.xml index f83c3284c..c3b0fb5bc 100644 --- a/res/values/colors.xml +++ b/res/values/colors.xml @@ -36,6 +36,11 @@ #33b5e5 + + #673ab7 + #7d57c1 + #ffffff + #4d000000 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index bcde855b5..206b44740 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -134,4 +134,15 @@ 4dp 36dp + + + 24dp + 16dp + 21dp + 24dp + 12dp + 4dp + 4dp + 11dp + 4dp diff --git a/res/values/styles.xml b/res/values/styles.xml index dab5c6aa1..7d5d42f8f 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -218,4 +218,18 @@ 2dp @color/background_dialer_call_log_list_item + + diff --git a/src/com/android/dialer/calllog/CallLogAdapter.java b/src/com/android/dialer/calllog/CallLogAdapter.java index 921ec506c..cc3c5bad8 100644 --- a/src/com/android/dialer/calllog/CallLogAdapter.java +++ b/src/com/android/dialer/calllog/CallLogAdapter.java @@ -18,16 +18,20 @@ package com.android.dialer.calllog; import android.content.Context; import android.content.Intent; +import android.content.SharedPreferences; import android.content.res.Resources; import android.database.Cursor; import android.net.Uri; import android.support.v7.widget.RecyclerView; import android.os.Bundle; import android.os.Trace; +import android.preference.PreferenceActivity; +import android.preference.PreferenceManager; import android.provider.CallLog; import android.support.v7.widget.RecyclerView.ViewHolder; import android.telecom.PhoneAccountHandle; import android.telephony.PhoneNumberUtils; +import android.telephony.TelephonyManager; import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; @@ -62,6 +66,21 @@ public class CallLogAdapter extends GroupingListAdapter private static final int VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM = 10; private static final int NO_EXPANDED_LIST_ITEM = -1; + private static final int VOICEMAIL_PROMO_CARD_POSITION = 0; + /** + * View type for voicemail promo card. Note: Numbering starts at 20 to avoid collision + * with {@link com.android.common.widget.GroupingListAdapter#ITEM_TYPE_IN_GROUP}, and + * {@link CallLogAdapter#VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM}. + */ + private static final int VIEW_TYPE_VOICEMAIL_PROMO_CARD = 20; + + /** + * The key for the show voicemail promo card preference which will determine whether the promo + * card was permanently dismissed or not. + */ + private static final String SHOW_VOICEMAIL_PROMO_CARD = "show_voicemail_promo_card"; + private static final boolean SHOW_VOICEMAIL_PROMO_CARD_DEFAULT = true; + protected final Context mContext; private final ContactInfoHelper mContactInfoHelper; private final VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; @@ -97,6 +116,10 @@ public class CallLogAdapter extends GroupingListAdapter private boolean mLoading = true; + private SharedPreferences mPrefs; + + private boolean mShowPromoCard = false; + /** Instance of helper class for managing views. */ private final CallLogListItemHelper mCallLogViewsHelper; @@ -135,6 +158,30 @@ public class CallLogAdapter extends GroupingListAdapter } }; + /** + * Click handler used to dismiss the promo card when the user taps the "ok" button. + */ + private final View.OnClickListener mOkActionListener = new View.OnClickListener() { + @Override + public void onClick(View view) { + dismissVoicemailPromoCard(); + } + }; + + /** + * Click handler used to send the user to the voicemail settings screen and then dismiss the + * promo card. + */ + private final View.OnClickListener mVoicemailSettingsActionListener = + new View.OnClickListener() { + @Override + public void onClick(View view) { + Intent intent = new Intent(TelephonyManager.ACTION_CONFIGURE_VOICEMAIL); + mContext.startActivity(intent); + dismissVoicemailPromoCard(); + } + }; + private void expandViewHolderActions(CallLogListItemViewHolder viewHolder) { // If another item is expanded, notify it that it has changed. Its actions will be // hidden when it is re-binded because we change mCurrentlyExpandedPosition below. @@ -212,6 +259,8 @@ public class CallLogAdapter extends GroupingListAdapter new PhoneCallDetailsHelper(mContext, resources, mPhoneNumberUtilsWrapper); mCallLogViewsHelper = new CallLogListItemHelper(phoneCallDetailsHelper, resources); mCallLogGroupBuilder = new CallLogGroupBuilder(this); + mPrefs = PreferenceManager.getDefaultSharedPreferences(context); + maybeShowVoicemailPromoCard(); } public void onSaveInstanceState(Bundle outState) { @@ -279,6 +328,8 @@ public class CallLogAdapter extends GroupingListAdapter public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { if (viewType == VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM) { return ShowCallHistoryViewHolder.create(mContext, parent); + } else if (viewType == VIEW_TYPE_VOICEMAIL_PROMO_CARD) { + return createVoicemailPromoCardViewHolder(parent); } return createCallLogEntryViewHolder(parent); } @@ -313,19 +364,52 @@ public class CallLogAdapter extends GroupingListAdapter * TODO: This gets called 20-30 times when Dialer starts up for a single call log entry and * should not. It invokes cross-process methods and the repeat execution can get costly. * - * @param callLogItemView the view corresponding to this entry - * @param count the number of entries in the current item, greater than 1 if it is a group + * @param ViewHolder The view corresponding to this entry. + * @param position The position of the entry. */ public void onBindViewHolder(ViewHolder viewHolder, int position) { - if (getItemViewType(position) == VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM) { - return; - } Trace.beginSection("onBindViewHolder: " + position); + + switch (getItemViewType(position)) { + case VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM: + break; + case VIEW_TYPE_VOICEMAIL_PROMO_CARD: + bindVoicemailPromoCardViewHolder(viewHolder); + break; + default: + bindCallLogListViewHolder(viewHolder, position); + break; + } + + Trace.endSection(); + } + + /** + * Binds the promo card view holder. + * + * @param viewHolder The promo card view holder. + */ + protected void bindVoicemailPromoCardViewHolder(ViewHolder viewHolder) { + PromoCardViewHolder promoCardViewHolder = (PromoCardViewHolder) viewHolder; + + promoCardViewHolder.getSettingsTextView().setOnClickListener( + mVoicemailSettingsActionListener); + promoCardViewHolder.getOkTextView().setOnClickListener(mOkActionListener); + } + + /** + * Binds the view holder for the call log list item view. + * + * @param viewHolder The call log list item view holder. + * @param position The position of the list item. + */ + + private void bindCallLogListViewHolder(ViewHolder viewHolder, int position) { Cursor c = (Cursor) getItem(position); if (c == null) { - Trace.endSection(); return; } + int count = getGroupSize(position); final String number = c.getString(CallLogQuery.NUMBER); @@ -428,22 +512,35 @@ public class CallLogAdapter extends GroupingListAdapter mViewTreeObserver = views.rootView.getViewTreeObserver(); mViewTreeObserver.addOnPreDrawListener(this); } - Trace.endSection(); } @Override public int getItemCount() { - return super.getItemCount() + (isShowingRecentsTab() ? 1 : 0); + return super.getItemCount() + ((isShowingRecentsTab() || mShowPromoCard) ? 1 : 0); } @Override public int getItemViewType(int position) { if (position == getItemCount() - 1 && isShowingRecentsTab()) { return VIEW_TYPE_SHOW_CALL_HISTORY_LIST_ITEM; + } else if (position == VOICEMAIL_PROMO_CARD_POSITION && mShowPromoCard) { + return VIEW_TYPE_VOICEMAIL_PROMO_CARD; } return super.getItemViewType(position); } + /** + * Retrieves an item at the specified position, taking into account the presence of a promo + * card. + * + * @param position The position to retrieve. + * @return The item at that position. + */ + @Override + public Object getItem(int position) { + return super.getItem(position - (mShowPromoCard ? 1 : 0)); + } + protected boolean isShowingRecentsTab() { return mIsShowingRecentsTab; } @@ -597,4 +694,37 @@ public class CallLogAdapter extends GroupingListAdapter return mContext.getResources().getString(R.string.call_log_header_other); } } + + /** + * Determines if the voicemail promo card should be shown or not. The voicemail promo card will + * be shown as the first item in the voicemail tab. + */ + private void maybeShowVoicemailPromoCard() { + boolean showPromoCard = mPrefs.getBoolean(SHOW_VOICEMAIL_PROMO_CARD, + SHOW_VOICEMAIL_PROMO_CARD_DEFAULT); + mShowPromoCard = (mVoicemailPlaybackPresenter != null) && showPromoCard; + } + + /** + * Dismisses the voicemail promo card and refreshes the call log. + */ + private void dismissVoicemailPromoCard() { + mPrefs.edit().putBoolean(SHOW_VOICEMAIL_PROMO_CARD, false).apply(); + mShowPromoCard = false; + notifyItemRemoved(VOICEMAIL_PROMO_CARD_POSITION); + } + + /** + * Creates the view holder for the voicemail promo card. + * + * @param parent The parent view. + * @return The {@link ViewHolder}. + */ + protected ViewHolder createVoicemailPromoCardViewHolder(ViewGroup parent) { + LayoutInflater inflater = LayoutInflater.from(mContext); + View view = inflater.inflate(R.layout.voicemail_promo_card, parent, false); + + PromoCardViewHolder viewHolder = PromoCardViewHolder.create(view); + return viewHolder; + } } diff --git a/src/com/android/dialer/calllog/PromoCardViewHolder.java b/src/com/android/dialer/calllog/PromoCardViewHolder.java new file mode 100644 index 000000000..4c9602759 --- /dev/null +++ b/src/com/android/dialer/calllog/PromoCardViewHolder.java @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2015 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.calllog; + +import com.android.dialer.R; + +import android.support.v7.widget.CardView; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +/** + * View holder class for a promo card which will appear in the voicemail tab. + */ +public class PromoCardViewHolder extends RecyclerView.ViewHolder { + public static PromoCardViewHolder create(View rootView) { + return new PromoCardViewHolder(rootView); + } + + /** + * The "Settings" button view. + */ + private View mSettingsTextView; + + /** + * The "Ok" button view. + */ + private View mOkTextView; + + /** + * Creates an instance of the {@link ViewHolder}. + * + * @param rootView The root view. + */ + private PromoCardViewHolder(View rootView) { + super(rootView); + + mSettingsTextView = rootView.findViewById(R.id.settings_action); + mOkTextView = rootView.findViewById(R.id.ok_action); + } + + /** + * Retrieves the "Settings" button. + * + * @return The view. + */ + public View getSettingsTextView() { + return mSettingsTextView; + } + + /** + * Retrieves the "Ok" button. + * + * @return The view. + */ + public View getOkTextView() { + return mOkTextView; + } +} -- cgit v1.2.3