diff options
Diffstat (limited to 'java/com/android/dialer/app/voicemail')
10 files changed, 227 insertions, 48 deletions
diff --git a/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java b/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java index fc6a37608..f40ed2794 100644 --- a/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java +++ b/java/com/android/dialer/app/voicemail/VoicemailPlaybackLayout.java @@ -30,7 +30,6 @@ import android.widget.LinearLayout; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.TextView; -import com.android.dialer.app.PhoneCallDetails; import com.android.dialer.app.R; import com.android.dialer.app.calllog.CallLogAsyncTaskUtil; import com.android.dialer.app.calllog.CallLogListItemViewHolder; @@ -347,16 +346,10 @@ public class VoicemailPlaybackLayout extends LinearLayout } @Override - public void onDeleteCall() {} - - @Override public void onDeleteVoicemail() { mPresenter.onVoicemailDeletedInDatabase(); } - @Override - public void onGetCallDetails(PhoneCallDetails[] details) {} - private String getString(int resId) { return mContext.getString(resId); } diff --git a/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java b/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java index 657022291..994160ff9 100644 --- a/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java +++ b/java/com/android/dialer/app/voicemail/VoicemailPlaybackPresenter.java @@ -39,6 +39,7 @@ import android.support.annotation.Nullable; import android.support.annotation.VisibleForTesting; import android.support.v4.content.FileProvider; import android.text.TextUtils; +import android.view.View; import android.view.WindowManager.LayoutParams; import android.webkit.MimeTypeMap; import com.android.common.io.MoreCloseables; @@ -47,8 +48,11 @@ import com.android.dialer.app.calllog.CallLogListItemViewHolder; import com.android.dialer.common.Assert; import com.android.dialer.common.AsyncTaskExecutor; import com.android.dialer.common.AsyncTaskExecutors; +import com.android.dialer.common.ConfigProviderBindings; import com.android.dialer.common.LogUtil; import com.android.dialer.constants.Constants; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.nano.DialerImpression; import com.android.dialer.phonenumbercache.CallLogQuery; import com.google.common.io.ByteStreams; import java.io.File; @@ -71,9 +75,9 @@ import javax.annotation.concurrent.ThreadSafe; * assumptions about the behaviors and lifecycle of the call log, in particular in the {@link * CallLogFragment} and {@link CallLogAdapter}. * - * <p>This controls a single {@link com.android.dialer.voicemail.VoicemailPlaybackLayout}. A single - * instance can be reused for different such layouts, using {@link #setPlaybackView}. This is to - * facilitate reuse across different voicemail call log entries. + * <p>This controls a single {@link com.android.dialer.app.voicemail.VoicemailPlaybackLayout}. A + * single instance can be reused for different such layouts, using {@link #setPlaybackView}. This is + * to facilitate reuse across different voicemail call log entries. * * <p>This class is not thread safe. The thread policy for this class is thread-confinement, all * calls into this class from outside must be done from the main UI thread. @@ -103,6 +107,8 @@ public class VoicemailPlaybackPresenter private static final String IS_SPEAKERPHONE_ON_KEY = VoicemailPlaybackPresenter.class.getName() + ".IS_SPEAKER_PHONE_ON"; private static final String VOICEMAIL_SHARE_FILE_NAME_DATE_FORMAT = "MM-dd-yy_hhmmaa"; + private static final String CONFIG_SHARE_VOICEMAIL_ALLOWED = "share_voicemail_allowed"; + private static VoicemailPlaybackPresenter sInstance; private static ScheduledExecutorService mScheduledExecutorService; /** @@ -138,6 +144,7 @@ public class VoicemailPlaybackPresenter private PowerManager.WakeLock mProximityWakeLock; private VoicemailAudioManager mVoicemailAudioManager; private OnVoicemailDeletedListener mOnVoicemailDeletedListener; + private View shareVoicemailButtonView; /** Initialize variables which are activity-independent and state-independent. */ protected VoicemailPlaybackPresenter(Activity activity) { @@ -222,11 +229,17 @@ public class VoicemailPlaybackPresenter /** Specify the view which this presenter controls and the voicemail to prepare to play. */ public void setPlaybackView( - PlaybackView view, long rowId, Uri voicemailUri, final boolean startPlayingImmediately) { + PlaybackView view, + long rowId, + Uri voicemailUri, + final boolean startPlayingImmediately, + View shareVoicemailButtonView) { mRowId = rowId; mView = view; mView.setPresenter(this, voicemailUri); mView.onSpeakerphoneOn(mIsSpeakerphoneOn); + this.shareVoicemailButtonView = shareVoicemailButtonView; + showShareVoicemailButton(false); // Handles cases where the same entry is binded again when scrolling in list, or where // the MediaPlayer was retained after an orientation change. @@ -236,6 +249,7 @@ public class VoicemailPlaybackPresenter // media player. mPosition = mMediaPlayer.getCurrentPosition(); onPrepared(mMediaPlayer); + showShareVoicemailButton(true); } else { if (!voicemailUri.equals(mVoicemailUri)) { mVoicemailUri = voicemailUri; @@ -247,19 +261,17 @@ public class VoicemailPlaybackPresenter * it if the content is not available. */ checkForContent( - new OnContentCheckedListener() { - @Override - public void onContentChecked(boolean hasContent) { - if (hasContent) { - prepareContent(); - } else { - if (startPlayingImmediately) { - requestContent(PLAYBACK_REQUEST); - } - if (mView != null) { - mView.resetSeekBar(); - mView.setClipPosition(0, mDuration.get()); - } + hasContent -> { + if (hasContent) { + showShareVoicemailButton(true); + prepareContent(); + } else { + if (startPlayingImmediately) { + requestContent(PLAYBACK_REQUEST); + } + if (mView != null) { + mView.resetSeekBar(); + mView.setClipPosition(0, mDuration.get()); } } }); @@ -547,6 +559,7 @@ public class VoicemailPlaybackPresenter mPosition = 0; mIsPlaying = false; + showShareVoicemailButton(false); } /** After done playing the voicemail clip, reset the clip position to the start. */ @@ -600,18 +613,16 @@ public class VoicemailPlaybackPresenter * timeout, but succeeded. */ checkForContent( - new OnContentCheckedListener() { - @Override - public void onContentChecked(boolean hasContent) { - if (!hasContent) { - // No local content, download from server. Queue playing if the request was - // issued, - mIsPlaying = requestContent(PLAYBACK_REQUEST); - } else { - // Queue playing once the media play loaded the content. - mIsPlaying = true; - prepareContent(); - } + hasContent -> { + if (!hasContent) { + // No local content, download from server. Queue playing if the request was + // issued, + mIsPlaying = requestContent(PLAYBACK_REQUEST); + } else { + showShareVoicemailButton(true); + // Queue playing once the media play loaded the content. + mIsPlaying = true; + prepareContent(); } }); return; @@ -813,6 +824,20 @@ public class VoicemailPlaybackPresenter sInstance = null; } + private void showShareVoicemailButton(boolean show) { + if (isShareVoicemailAllowed(mContext) && shareVoicemailButtonView != null) { + if (show) { + Logger.get(mContext).logImpression(DialerImpression.Type.VVM_SHARE_VISIBLE); + } + LogUtil.d("VoicemailPlaybackPresenter.showShareVoicemailButton", "show: %b", show); + shareVoicemailButtonView.setVisibility(show ? View.VISIBLE : View.GONE); + } + } + + private static boolean isShareVoicemailAllowed(Context context) { + return ConfigProviderBindings.get(context).getBoolean(CONFIG_SHARE_VOICEMAIL_ALLOWED, true); + } + /** * Share voicemail to be opened by user selected apps. This method will collect information, copy * voicemail to a temporary file in background and launch a chooser intent to share it. @@ -1041,6 +1066,7 @@ public class VoicemailPlaybackPresenter public void onPostExecute(Boolean hasContent) { if (hasContent && mContext != null && mIsWaitingForResult.getAndSet(false)) { mContext.getContentResolver().unregisterContentObserver(FetchResultHandler.this); + showShareVoicemailButton(true); prepareContent(); } } diff --git a/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java b/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java index e36406d17..190426e6e 100644 --- a/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java @@ -17,10 +17,18 @@ package com.android.dialer.app.voicemail.error; import android.content.Context; +import android.preference.PreferenceManager; import android.provider.VoicemailContract.Status; import android.support.annotation.Nullable; +import android.telecom.PhoneAccountHandle; import com.android.dialer.app.voicemail.error.VoicemailErrorMessage.Action; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.PerAccountSharedPreferences; +import com.android.dialer.logging.Logger; +import com.android.dialer.logging.nano.DialerImpression; +import com.android.voicemail.VoicemailClient; +import com.android.voicemail.VoicemailComponent; import java.util.ArrayList; import java.util.List; @@ -32,14 +40,18 @@ public class OmtpVoicemailMessageCreator { private static final float QUOTA_NEAR_FULL_THRESHOLD = 0.9f; private static final float QUOTA_FULL_THRESHOLD = 0.99f; + protected static final String VOICEMAIL_PROMO_DISMISSED_KEY = + "voicemail_archive_promo_was_dismissed"; + protected static final String VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY = + "voicemail_archive_almost_full_promo_was_dismissed"; @Nullable - public static VoicemailErrorMessage create(Context context, VoicemailStatus status) { + public static VoicemailErrorMessage create( + Context context, VoicemailStatus status, final VoicemailStatusReader statusReader) { if (Status.CONFIGURATION_STATE_OK == status.configurationState && Status.DATA_CHANNEL_STATE_OK == status.dataChannelState && Status.NOTIFICATION_CHANNEL_STATE_OK == status.notificationChannelState) { - - return checkQuota(context, status); + return checkQuota(context, status, statusReader); } // Initial state when the source is activating. Other error might be written into data and // notification channel during activation. @@ -120,24 +132,98 @@ public class OmtpVoicemailMessageCreator { } @Nullable - private static VoicemailErrorMessage checkQuota(Context context, VoicemailStatus status) { + private static VoicemailErrorMessage checkQuota( + Context context, VoicemailStatus status, VoicemailStatusReader statusReader) { if (status.quotaOccupied != Status.QUOTA_UNAVAILABLE && status.quotaTotal != Status.QUOTA_UNAVAILABLE) { + + PhoneAccountHandle phoneAccountHandle = status.getPhoneAccountHandle(); + + VoicemailClient voicemailClient = VoicemailComponent.get(context).getVoicemailClient(); + + PerAccountSharedPreferences sharedPreferenceForAccount = + new PerAccountSharedPreferences( + context, phoneAccountHandle, PreferenceManager.getDefaultSharedPreferences(context)); + + boolean isVoicemailArchiveEnabled = + VoicemailComponent.get(context) + .getVoicemailClient() + .isVoicemailArchiveEnabled(context, phoneAccountHandle); + if ((float) status.quotaOccupied / (float) status.quotaTotal >= QUOTA_FULL_THRESHOLD) { - return new VoicemailErrorMessage( + return createInboxErrorMessage( + context, + status, + status.getPhoneAccountHandle(), + statusReader, + sharedPreferenceForAccount, + voicemailClient, + isVoicemailArchiveEnabled, + context.getString(R.string.voicemail_error_inbox_full_turn_archive_on_title), + context.getString(R.string.voicemail_error_inbox_full_turn_archive_on_message), context.getString(R.string.voicemail_error_inbox_full_title), - context.getString(R.string.voicemail_error_inbox_full_message)); + context.getString(R.string.voicemail_error_inbox_full_message), + VOICEMAIL_PROMO_DISMISSED_KEY); } if ((float) status.quotaOccupied / (float) status.quotaTotal >= QUOTA_NEAR_FULL_THRESHOLD) { - return new VoicemailErrorMessage( + return createInboxErrorMessage( + context, + status, + status.getPhoneAccountHandle(), + statusReader, + sharedPreferenceForAccount, + voicemailClient, + isVoicemailArchiveEnabled, + context.getString(R.string.voicemail_error_inbox_almost_full_turn_archive_on_title), + context.getString(R.string.voicemail_error_inbox_almost_full_turn_archive_on_message), context.getString(R.string.voicemail_error_inbox_near_full_title), - context.getString(R.string.voicemail_error_inbox_near_full_message)); + context.getString(R.string.voicemail_error_inbox_near_full_message), + VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY); } } return null; } + private static VoicemailErrorMessage createInboxErrorMessage( + Context context, + VoicemailStatus status, + PhoneAccountHandle phoneAccountHandle, + VoicemailStatusReader statusReader, + PerAccountSharedPreferences sharedPreferenceForAccount, + VoicemailClient voicemailClient, + boolean isVoicemailArchiveEnabled, + String promoTitle, + String promoMessage, + String nonPromoTitle, + String nonPromoMessage, + String preferenceKey) { + + boolean wasPromoDismissed = sharedPreferenceForAccount.getBoolean(preferenceKey, false); + + if (!wasPromoDismissed && !isVoicemailArchiveEnabled) { + logArchiveImpression( + context, + preferenceKey, + DialerImpression.Type.VVM_USER_SHOWN_VM_ALMOST_FULL_PROMO, + DialerImpression.Type.VVM_USER_SHOWN_VM_FULL_PROMO); + return new VoicemailErrorMessage( + promoTitle, + promoMessage, + VoicemailErrorMessage.createDismissTurnArchiveOnAction( + context, statusReader, sharedPreferenceForAccount, preferenceKey), + VoicemailErrorMessage.createTurnArchiveOnAction( + context, status, voicemailClient, phoneAccountHandle, preferenceKey)); + } else { + logArchiveImpression( + context, + preferenceKey, + DialerImpression.Type.VVM_USER_SHOWN_VM_ALMOST_FULL_ERROR_MESSAGE, + DialerImpression.Type.VVM_USER_SHOWN_VM_FULL_ERROR_MESSAGE); + return new VoicemailErrorMessage(nonPromoTitle, nonPromoMessage); + } + } + @Nullable private static VoicemailErrorMessage createNoSignalMessage( Context context, VoicemailStatus status) { @@ -174,4 +260,15 @@ public class OmtpVoicemailMessageCreator { } return new VoicemailErrorMessage(title, description, actions); } + + protected static void logArchiveImpression( + Context context, String preference, int vmAlmostFullImpression, int vmFullImpression) { + if (preference.equals(VOICEMAIL_PROMO_DISMISSED_KEY)) { + Logger.get(context).logImpression(vmAlmostFullImpression); + } else if (preference.equals(VOICEMAIL_PROMO_ALMOST_FULL_DISMISSED_KEY)) { + Logger.get(context).logImpression(vmFullImpression); + } else { + throw Assert.createAssertionFailException("Invalid preference key " + preference); + } + } } diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java index 61572008b..f85d91186 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessage.java @@ -22,12 +22,15 @@ import android.provider.Settings; import android.provider.VoicemailContract; import android.support.annotation.NonNull; import android.support.annotation.Nullable; +import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; import android.view.View; import android.view.View.OnClickListener; +import com.android.dialer.common.PerAccountSharedPreferences; import com.android.dialer.logging.Logger; import com.android.dialer.logging.nano.DialerImpression; import com.android.dialer.util.CallUtil; +import com.android.voicemail.VoicemailClient; import java.util.Arrays; import java.util.List; @@ -175,4 +178,52 @@ public class VoicemailErrorMessage { } }); } + + @NonNull + public static Action createTurnArchiveOnAction( + final Context context, + final VoicemailStatus status, + VoicemailClient voicemailClient, + PhoneAccountHandle phoneAccountHandle, + String preference) { + return new Action( + context.getString(R.string.voicemail_action_turn_archive_on), + new OnClickListener() { + @Override + public void onClick(View v) { + OmtpVoicemailMessageCreator.logArchiveImpression( + context, + preference, + DialerImpression.Type.VVM_USER_ENABLED_ARCHIVE_FROM_VM_FULL_PROMO, + DialerImpression.Type.VVM_USER_ENABLED_ARCHIVE_FROM_VM_ALMOST_FULL_PROMO); + + voicemailClient.setVoicemailArchiveEnabled(context, phoneAccountHandle, true); + Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); + intent.setPackage(status.sourcePackage); + context.sendBroadcast(intent); + } + }); + } + + @NonNull + public static Action createDismissTurnArchiveOnAction( + final Context context, + VoicemailStatusReader statusReader, + PerAccountSharedPreferences sharedPreferenceForAccount, + String preferenceKeyToUpdate) { + return new Action( + context.getString(R.string.voicemail_action_dimiss), + new OnClickListener() { + @Override + public void onClick(View v) { + OmtpVoicemailMessageCreator.logArchiveImpression( + context, + preferenceKeyToUpdate, + DialerImpression.Type.VVM_USER_DISMISSED_VM_FULL_PROMO, + DialerImpression.Type.VVM_USER_DISMISSED_VM_ALMOST_FULL_PROMO); + sharedPreferenceForAccount.edit().putBoolean(preferenceKeyToUpdate, true); + statusReader.refresh(); + } + }); + } } diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java index 5ebef801d..7dc18f043 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java @@ -39,7 +39,7 @@ public class VoicemailErrorMessageCreator { case Vvm3VoicemailMessageCreator.VVM_TYPE_VVM3: return Vvm3VoicemailMessageCreator.create(context, status, statusReader); default: - return OmtpVoicemailMessageCreator.create(context, status); + return OmtpVoicemailMessageCreator.create(context, status, statusReader); } } } diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailStatus.java b/java/com/android/dialer/app/voicemail/error/VoicemailStatus.java index a09941de2..c429d6dcc 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailStatus.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailStatus.java @@ -16,6 +16,7 @@ package com.android.dialer.app.voicemail.error; +import android.content.ComponentName; import android.content.Context; import android.database.Cursor; import android.net.Uri; @@ -25,6 +26,7 @@ import android.provider.Settings; import android.provider.Settings.Global; import android.provider.VoicemailContract.Status; import android.support.annotation.Nullable; +import android.telecom.PhoneAccountHandle; import android.telephony.TelephonyManager; import com.android.dialer.database.VoicemailStatusQuery; @@ -257,4 +259,9 @@ public class VoicemailStatus { } return cursor.getString(index); } + + public PhoneAccountHandle getPhoneAccountHandle() { + return new PhoneAccountHandle( + ComponentName.unflattenFromString(phoneAccountComponentName), phoneAccountId); + } } diff --git a/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java b/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java index 6e9405cbf..356131bb3 100644 --- a/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java @@ -269,7 +269,7 @@ public class Vvm3VoicemailMessageCreator { VoicemailErrorMessage.createSetPinAction(context)); } - return OmtpVoicemailMessageCreator.create(context, status); + return OmtpVoicemailMessageCreator.create(context, status, statusReader); } @NonNull diff --git a/java/com/android/dialer/app/voicemail/error/res/layout/voicemai_error_message_fragment.xml b/java/com/android/dialer/app/voicemail/error/res/layout/voicemai_error_message_fragment.xml index 0dfb1c2fd..4a40857a0 100644 --- a/java/com/android/dialer/app/voicemail/error/res/layout/voicemai_error_message_fragment.xml +++ b/java/com/android/dialer/app/voicemail/error/res/layout/voicemai_error_message_fragment.xml @@ -48,7 +48,6 @@ <TextView android:id="@+id/error_card_details" - android:autoLink="web" android:layout_width="wrap_content" android:layout_height="wrap_content" android:lineSpacingExtra="@dimen/alert_line_spacing" diff --git a/java/com/android/dialer/app/voicemail/error/res/layout/voicemail_tos_fragment.xml b/java/com/android/dialer/app/voicemail/error/res/layout/voicemail_tos_fragment.xml index 2b9d17328..c193eaa47 100644 --- a/java/com/android/dialer/app/voicemail/error/res/layout/voicemail_tos_fragment.xml +++ b/java/com/android/dialer/app/voicemail/error/res/layout/voicemail_tos_fragment.xml @@ -31,7 +31,6 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:paddingBottom="16dp" - android:autoLink="web" android:text="@string/verizon_terms_and_conditions_1.1_english" android:textColor="@color/secondary_text_color" android:textSize="@dimen/call_log_detail_text_size"/> diff --git a/java/com/android/dialer/app/voicemail/error/res/values/strings.xml b/java/com/android/dialer/app/voicemail/error/res/values/strings.xml index 1d39b9dcb..94d3dba11 100644 --- a/java/com/android/dialer/app/voicemail/error/res/values/strings.xml +++ b/java/com/android/dialer/app/voicemail/error/res/values/strings.xml @@ -54,6 +54,11 @@ <string name="voicemail_error_inbox_full_title">Can\'t receive new voicemails</string> <string name="voicemail_error_inbox_full_message">Your inbox is full. Try deleting some messages to receive new voicemail.</string> + <string name="voicemail_error_inbox_full_turn_archive_on_title">Turn on extra storage and backup</string> + <string name="voicemail_error_inbox_full_turn_archive_on_message">Your mailbox is full. To free up space, turn on extra storage so Google can manage and backup your voicemail messages.</string> + + <string name="voicemail_error_inbox_almost_full_turn_archive_on_title">Turn on extra storage and backup</string> + <string name="voicemail_error_inbox_almost_full_turn_archive_on_message">Your mailbox is almost full. To free up space, turn on extra storage so Google can manage and backup your voicemail messages.</string> <string name="voicemail_error_pin_not_set_title">Set your voicemail PIN</string> <string name="voicemail_error_pin_not_set_message">You\'ll need a voicemail PIN anytime you call to access your voicemail.</string> @@ -63,6 +68,8 @@ <string name="voicemail_action_turn_off_airplane_mode">Airplane Mode Settings</string> <string name="voicemail_action_set_pin">Set PIN</string> <string name="voicemail_action_retry">Try Again</string> + <string name="voicemail_action_turn_archive_on">Turn on</string> + <string name="voicemail_action_dimiss">No Thanks</string> <string name="voicemail_action_sync">Sync</string> <string name="voicemail_action_call_voicemail">Call Voicemail</string> <string name="voicemail_action_call_customer_support">Call Customer Support</string> |