diff options
Diffstat (limited to 'java')
5 files changed, 164 insertions, 4 deletions
diff --git a/java/com/android/dialer/app/calllog/VisualVoicemailCallLogFragment.java b/java/com/android/dialer/app/calllog/VisualVoicemailCallLogFragment.java index 17018b38d..6882ef9d8 100644 --- a/java/com/android/dialer/app/calllog/VisualVoicemailCallLogFragment.java +++ b/java/com/android/dialer/app/calllog/VisualVoicemailCallLogFragment.java @@ -17,12 +17,14 @@ package com.android.dialer.app.calllog; import android.app.KeyguardManager; +import android.content.Context; import android.content.Intent; import android.database.ContentObserver; import android.media.AudioManager; import android.os.Bundle; import android.provider.CallLog; import android.provider.VoicemailContract; +import android.support.annotation.VisibleForTesting; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; @@ -31,15 +33,22 @@ import com.android.dialer.app.list.ListsFragment; import com.android.dialer.app.voicemail.VoicemailAudioManager; import com.android.dialer.app.voicemail.VoicemailErrorManager; import com.android.dialer.app.voicemail.VoicemailPlaybackPresenter; +import com.android.dialer.app.voicemail.error.VoicemailErrorMessageCreator; +import com.android.dialer.app.voicemail.error.VoicemailStatus; +import com.android.dialer.app.voicemail.error.VoicemailStatusWorker; import com.android.dialer.common.LogUtil; +import com.android.dialer.common.concurrent.DialerExecutor; +import com.android.dialer.common.concurrent.DialerExecutors; import com.android.dialer.logging.DialerImpression; import com.android.dialer.logging.Logger; import com.android.dialer.util.PermissionsUtil; +import java.util.List; public class VisualVoicemailCallLogFragment extends CallLogFragment { private final ContentObserver mVoicemailStatusObserver = new CustomContentObserver(); private VoicemailPlaybackPresenter mVoicemailPlaybackPresenter; + private DialerExecutor<Context> mPreSyncVoicemailStatusCheckExecutor; private VoicemailErrorManager mVoicemailErrorManager; @@ -56,7 +65,6 @@ public class VisualVoicemailCallLogFragment extends CallLogFragment { public void onActivityCreated(Bundle savedInstanceState) { mVoicemailPlaybackPresenter = VoicemailPlaybackPresenter.getInstance(getActivity(), savedInstanceState); - if (PermissionsUtil.hasReadVoicemailPermissions(getContext()) && PermissionsUtil.hasAddVoicemailPermissions(getContext())) { getActivity() @@ -69,6 +77,13 @@ public class VisualVoicemailCallLogFragment extends CallLogFragment { "read voicemail permission unavailable."); } super.onActivityCreated(savedInstanceState); + + mPreSyncVoicemailStatusCheckExecutor = + DialerExecutors.createUiTaskBuilder( + getFragmentManager(), "fetchVoicemailStatus", new VoicemailStatusWorker()) + .onSuccess(this::onPreSyncVoicemailStatusChecked) + .build(); + mVoicemailErrorManager = new VoicemailErrorManager(getContext(), getAdapter().getAlertManager(), mModalAlertManager); @@ -136,14 +151,38 @@ public class VisualVoicemailCallLogFragment extends CallLogFragment { LogUtil.enterBlock("VisualVoicemailCallLogFragment.onVisible"); super.onVisible(); if (getActivity() != null) { - Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); - intent.setPackage(getActivity().getPackageName()); - getActivity().sendBroadcast(intent); + mPreSyncVoicemailStatusCheckExecutor.executeParallel(getActivity()); Logger.get(getActivity()).logImpression(DialerImpression.Type.VVM_TAB_VIEWED); getActivity().setVolumeControlStream(VoicemailAudioManager.PLAYBACK_STREAM); } } + private void onPreSyncVoicemailStatusChecked(List<VoicemailStatus> statuses) { + if (!shouldAutoSync(new VoicemailErrorMessageCreator(), statuses)) { + return; + } + + Intent intent = new Intent(VoicemailContract.ACTION_SYNC_VOICEMAIL); + intent.setPackage(getActivity().getPackageName()); + getActivity().sendBroadcast(intent); + } + + @VisibleForTesting + static boolean shouldAutoSync( + VoicemailErrorMessageCreator errorMessageCreator, List<VoicemailStatus> statuses) { + for (VoicemailStatus status : statuses) { + if (!status.isActive()) { + continue; + } + if (errorMessageCreator.isSyncBlockingError(status)) { + LogUtil.i( + "VisualVoicemailCallLogFragment.shouldAutoSync", "auto-sync blocked due to " + status); + return false; + } + } + return true; + } + @Override public void onNotVisible() { LogUtil.enterBlock("VisualVoicemailCallLogFragment.onNotVisible"); diff --git a/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java b/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java index 909de70bb..79e038332 100644 --- a/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/OmtpVoicemailMessageCreator.java @@ -136,6 +136,25 @@ public class OmtpVoicemailMessageCreator { return null; } + public static boolean isSyncBlockingError(VoicemailStatus status) { + if (status.notificationChannelState != Status.NOTIFICATION_CHANNEL_STATE_OK) { + return true; + } + + if (status.dataChannelState != Status.DATA_CHANNEL_STATE_OK) { + return true; + } + + switch (status.configurationState) { + case Status.CONFIGURATION_STATE_OK: + // allow activation to be queued again in case it is interrupted + case Status.CONFIGURATION_STATE_CONFIGURING: + return false; + default: + return true; + } + } + @Nullable private static VoicemailErrorMessage checkQuota( Context context, VoicemailStatus status, VoicemailStatusReader statusReader) { diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java index 2048d4958..44ceb893e 100644 --- a/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/VoicemailErrorMessageCreator.java @@ -43,4 +43,13 @@ public class VoicemailErrorMessageCreator { return OmtpVoicemailMessageCreator.create(context, status, statusReader); } } + + public boolean isSyncBlockingError(VoicemailStatus status) { + switch (status.type) { + case VisualVoicemailTypeExtensions.VVM_TYPE_VVM3: + return Vvm3VoicemailMessageCreator.isSyncBlockingError(status); + default: + return OmtpVoicemailMessageCreator.isSyncBlockingError(status); + } + } } diff --git a/java/com/android/dialer/app/voicemail/error/VoicemailStatusWorker.java b/java/com/android/dialer/app/voicemail/error/VoicemailStatusWorker.java new file mode 100644 index 000000000..95b16e8f3 --- /dev/null +++ b/java/com/android/dialer/app/voicemail/error/VoicemailStatusWorker.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2017 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.app.voicemail.error; + +import android.annotation.TargetApi; +import android.content.Context; +import android.database.Cursor; +import android.os.Build.VERSION_CODES; +import android.provider.VoicemailContract.Status; +import android.support.annotation.Nullable; +import com.android.dialer.common.concurrent.DialerExecutor.Worker; +import com.android.dialer.database.VoicemailStatusQuery; +import com.android.dialer.telecom.TelecomUtil; +import com.android.voicemail.VoicemailComponent; +import java.util.ArrayList; +import java.util.List; + +/** + * Worker for {@link com.android.dialer.common.concurrent.DialerExecutors} to fetch voicemail status + */ +@TargetApi(VERSION_CODES.M) +public class VoicemailStatusWorker implements Worker<Context, List<VoicemailStatus>> { + + @Nullable + @Override + public List<VoicemailStatus> doInBackground(@Nullable Context context) throws Throwable { + List<VoicemailStatus> statuses = new ArrayList<>(); + if (!TelecomUtil.hasReadWriteVoicemailPermissions(context)) { + return statuses; + } + StringBuilder where = new StringBuilder(); + java.util.List<String> selectionArgs = new ArrayList<>(); + + VoicemailComponent.get(context) + .getVoicemailClient() + .appendOmtpVoicemailStatusSelectionClause(context, where, selectionArgs); + + try (Cursor cursor = + context + .getContentResolver() + .query( + Status.CONTENT_URI, + VoicemailStatusQuery.getProjection(), + where.toString(), + selectionArgs.toArray(new String[selectionArgs.size()]), + null)) { + if (cursor == null) { + return statuses; + } + + for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) { + statuses.add(new VoicemailStatus(context, cursor)); + } + } + + return statuses; + } +} diff --git a/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java b/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java index d3024f4c5..8e8106b44 100644 --- a/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java +++ b/java/com/android/dialer/app/voicemail/error/Vvm3VoicemailMessageCreator.java @@ -20,6 +20,7 @@ import android.content.Context; import android.content.Intent; import android.net.Uri; import android.os.Build.VERSION_CODES; +import android.provider.VoicemailContract.Status; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.RequiresApi; @@ -257,6 +258,26 @@ public class Vvm3VoicemailMessageCreator { return OmtpVoicemailMessageCreator.create(context, status, statusReader); } + public static boolean isSyncBlockingError(VoicemailStatus status) { + if (status.notificationChannelState != Status.NOTIFICATION_CHANNEL_STATE_OK) { + return true; + } + + if (status.dataChannelState != Status.DATA_CHANNEL_STATE_OK) { + return true; + } + + switch (status.configurationState) { + case PIN_NOT_SET: + case Status.CONFIGURATION_STATE_OK: + // allow activation to be queued again in case it is interrupted + case Status.CONFIGURATION_STATE_CONFIGURING: + return false; + default: + return true; + } + } + @NonNull private static CharSequence getCustomerSupportString(Context context, int id) { // TODO(twyen): get number based on the country the user is currently in. |