From 210452f13a70de30a46c4ee2aa41668f840dfefd Mon Sep 17 00:00:00 2001 From: uabdullah Date: Wed, 28 Feb 2018 15:54:50 -0800 Subject: Show empty view when there are no voicemails When there are no voicemails to be shown, we show an empty view. This is done by hiding the recycler view and showing the empty view. Similarly when a voicemail is present, we hide the empty view and then show the recycler view. Bug: 25661977 Test: Unit Tests PiperOrigin-RevId: 187396952 Change-Id: Ifa718fb05c1be37aabdf4c91bc2c1653357565b2 --- .../voicemail/listui/NewVoicemailFragment.java | 40 +++++++++++++++++++--- .../res/layout/new_voicemail_call_log_fragment.xml | 28 +++++++++++---- .../dialer/voicemail/listui/res/values/strings.xml | 3 ++ .../widget/res/layout/empty_content_view.xml | 2 +- 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java index 9296d04e7..6d71dade9 100644 --- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java +++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java @@ -30,6 +30,7 @@ import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.FrameLayout; import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.RefreshAnnotatedCallLogReceiver; import com.android.dialer.common.LogUtil; @@ -38,6 +39,7 @@ import com.android.dialer.common.concurrent.UiListener; import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent; import com.android.dialer.voicemail.listui.error.VoicemailStatus; import com.android.dialer.voicemailstatus.VoicemailStatusQuery; +import com.android.dialer.widget.EmptyContentView; import com.android.voicemail.VoicemailComponent; import com.google.common.collect.ImmutableList; import com.google.common.util.concurrent.ListenableFuture; @@ -52,6 +54,11 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba private RefreshAnnotatedCallLogReceiver refreshAnnotatedCallLogReceiver; private UiListener> queryVoicemailStatusTableListener; + // View required to show/hide recycler and empty views + FrameLayout fragmentRootFrameLayout; + + private EmptyContentView emptyContentView; + public NewVoicemailFragment() { LogUtil.enterBlock("NewVoicemailFragment.NewVoicemailFragment"); } @@ -147,10 +154,14 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba public View onCreateView( LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { LogUtil.enterBlock("NewVoicemailFragment.onCreateView"); - View view = inflater.inflate(R.layout.new_voicemail_call_log_fragment, container, false); - recyclerView = view.findViewById(R.id.new_voicemail_call_log_recycler_view); + + fragmentRootFrameLayout = + (FrameLayout) inflater.inflate(R.layout.new_voicemail_call_log_fragment, container, false); + recyclerView = fragmentRootFrameLayout.findViewById(R.id.new_voicemail_call_log_recycler_view); + + emptyContentView = fragmentRootFrameLayout.findViewById(R.id.empty_content_view); getLoaderManager().restartLoader(0, null, this); - return view; + return fragmentRootFrameLayout; } @Override @@ -162,6 +173,12 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba @Override public void onLoadFinished(Loader loader, Cursor data) { LogUtil.i("NewVoicemailFragment.onLoadFinished", "cursor size is %d", data.getCount()); + if (data.getCount() == 0) { + showEmptyVoicemailFragmentView(); + return; + } + showView(recyclerView); + if (recyclerView.getAdapter() == null) { recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); // TODO(uabdullah): Replace getActivity().getFragmentManager() with getChildFragment() @@ -182,9 +199,24 @@ public final class NewVoicemailFragment extends Fragment implements LoaderCallba recyclerView.getAdapter()); ((NewVoicemailAdapter) recyclerView.getAdapter()).updateCursor(data); ((NewVoicemailAdapter) recyclerView.getAdapter()).checkAndPlayVoicemail(); + queryAndUpdateVoicemailStatusAlert(); } + } + + /** Shows the view when there are no voicemails to be displayed * */ + private void showEmptyVoicemailFragmentView() { + LogUtil.enterBlock("NewVoicemailFragmentListener.showEmptyVoicemailFragmentView"); + + showView(emptyContentView); + + emptyContentView.setDescription((R.string.empty_voicemail_tab_text)); + emptyContentView.setImage(R.drawable.quantum_ic_schedule_vd_theme_24); + } - queryAndUpdateVoicemailStatusAlert(); + private void showView(View view) { + LogUtil.i("NewVoicemailFragmentListener.showView", "Showing view: " + view); + emptyContentView.setVisibility(view == emptyContentView ? View.VISIBLE : View.GONE); + recyclerView.setVisibility(view == recyclerView ? View.VISIBLE : View.GONE); } private void registerRefreshAnnotatedCallLogReceiver() { diff --git a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_call_log_fragment.xml b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_call_log_fragment.xml index 9daa3e114..fd9e0f2d2 100644 --- a/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_call_log_fragment.xml +++ b/java/com/android/dialer/voicemail/listui/res/layout/new_voicemail_call_log_fragment.xml @@ -15,21 +15,35 @@ ~ limitations under the License --> - - + android:background="@color/background_dialer_light" + android:clipToPadding="false" + android:visibility="gone" + /> + + + + + + + diff --git a/java/com/android/dialer/voicemail/listui/res/values/strings.xml b/java/com/android/dialer/voicemail/listui/res/values/strings.xml index db33c1909..d12a71ee6 100644 --- a/java/com/android/dialer/voicemail/listui/res/values/strings.xml +++ b/java/com/android/dialer/voicemail/listui/res/values/strings.xml @@ -57,4 +57,7 @@ If you do not accept all of these terms and conditions, do not use Visual Voice Transcribed by Google + + Your voicemail inbox is empty. + diff --git a/java/com/android/dialer/widget/res/layout/empty_content_view.xml b/java/com/android/dialer/widget/res/layout/empty_content_view.xml index 177744385..9aac6f48f 100644 --- a/java/com/android/dialer/widget/res/layout/empty_content_view.xml +++ b/java/com/android/dialer/widget/res/layout/empty_content_view.xml @@ -18,7 +18,7 @@ Date: Wed, 28 Feb 2018 16:21:47 -0800 Subject: Parity of OldMainActivityPeer with ListsFragment for VM This CL helps to ensure that when the VVM settings toggle is turned on or off, or a sim is swapped, inserted or removed the VM tab disappears and appears, just like it currently does. When a VM tab disappears we also move to the speed dial index. Bug: 73123614,73998717 Test: N/A PiperOrigin-RevId: 187400703 Change-Id: I76a0b43da86713caa67956413a39299c7ecbc8d1 --- .../dialer/main/impl/OldMainActivityPeer.java | 75 +++++++++++++++++++++- .../dialer/main/impl/bottomnav/BottomNavBar.java | 18 ++++++ 2 files changed, 90 insertions(+), 3 deletions(-) diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java index a05ef6d16..2999c6b0b 100644 --- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java +++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java @@ -23,11 +23,14 @@ import android.app.KeyguardManager; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; +import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.provider.CallLog.Calls; import android.provider.ContactsContract.QuickContact; +import android.provider.VoicemailContract; import android.support.annotation.Nullable; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; @@ -91,9 +94,15 @@ import com.android.dialer.smartdial.util.SmartDialPrefix; import com.android.dialer.storage.StorageComponent; import com.android.dialer.telecom.TelecomUtil; import com.android.dialer.util.DialerUtils; +import com.android.dialer.util.PermissionsUtil; import com.android.dialer.util.TransactionSafeActivity; +import com.android.dialer.voicemail.listui.error.VoicemailStatusCorruptionHandler; +import com.android.dialer.voicemail.listui.error.VoicemailStatusCorruptionHandler.Source; +import com.android.dialer.voicemailstatus.VisualVoicemailEnabledChecker; +import com.android.dialer.voicemailstatus.VoicemailStatusHelper; import com.android.voicemail.VoicemailComponent; import com.google.common.util.concurrent.ListenableFuture; +import java.util.Locale; import java.util.concurrent.TimeUnit; /** @@ -273,7 +282,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen if (VoicemailComponent.get(context) .getVoicemailClient() .isVoicemailEnabled(context, defaultUserSelectedAccount)) { - LogUtil.i("OldMainActivityPeer.canVoicemailTabBeShown", "Voicemail is not enabled"); + LogUtil.i("OldMainActivityPeer.canVoicemailTabBeShown", "Voicemail is enabled"); return true; } LogUtil.i("OldMainActivityPeer.canVoicemailTabBeShown", "returning false"); @@ -706,7 +715,6 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen *
  • Marking missed calls as read when appropriate. See {@link * #markMissedCallsAsReadAndRemoveNotification()} *
  • TODO(calderwoodra): multiselect - *
  • TODO(calderwoodra): voicemail status * * * @see CallLogFragmentListener @@ -727,6 +735,15 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen private long timeSelected = -1; private boolean activityIsAlive; + private final ContentObserver voicemailStatusObserver = + new ContentObserver(new Handler()) { + @Override + public void onChange(boolean selfChange) { + super.onChange(selfChange); + callLogQueryHandler.fetchVoicemailStatus(); + } + }; + MainCallLogFragmentListener( Context context, ContentResolver contentResolver, @@ -738,6 +755,21 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen this.toolbar = toolbar; } + private void registerVoicemailStatusContentObserver(Context context) { + + if (PermissionsUtil.hasReadVoicemailPermissions(context) + && PermissionsUtil.hasAddVoicemailPermissions(context)) { + context + .getContentResolver() + .registerContentObserver( + VoicemailContract.Status.CONTENT_URI, true, voicemailStatusObserver); + } else { + LogUtil.w( + "MainCallLogFragmentListener.registerVoicemailStatusContentObserver", + "no voicemail read/add permissions"); + } + } + @Override public void updateTabUnreadCounts() { callLogQueryHandler.fetchMissedCallsUnreadCount(); @@ -752,7 +784,42 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen @Override public void onVoicemailStatusFetched(Cursor statusCursor) { - // TODO(calderwoodra): handle this when voicemail is implemented + LogUtil.i("OldMainActivityPeer.MainCallLogFragmentListener", "onVoicemailStatusFetched"); + VoicemailStatusCorruptionHandler.maybeFixVoicemailStatus( + context, statusCursor, Source.Activity); + + // Update hasActiveVoicemailProvider, which controls the number of tabs displayed. + int numberOfActiveVoicemailSources = + VoicemailStatusHelper.getNumberActivityVoicemailSources(statusCursor); + + boolean hasActiveVoicemailProvider = numberOfActiveVoicemailSources > 0; + LogUtil.i( + "OldMainActivityPeer.onVoicemailStatusFetched", + String.format( + Locale.US, + "hasActiveVoicemailProvider:%b, number of active voicemail sources:%d", + hasActiveVoicemailProvider, + numberOfActiveVoicemailSources)); + + if (hasActiveVoicemailProvider) { + // TODO(yueg): Use new logging for VVM_TAB_VISIBLE + // Logger.get(context).logImpression(DialerImpression.Type.VVM_TAB_VISIBLE); + bottomNavBar.showVoicemail(true); + callLogQueryHandler.fetchVoicemailUnreadCount(); + } else { + bottomNavBar.showVoicemail(false); + } + + StorageComponent.get(context) + .unencryptedSharedPrefs() + .edit() + .putBoolean( + VisualVoicemailEnabledChecker.PREF_KEY_HAS_ACTIVE_VOICEMAIL_PROVIDER, + hasActiveVoicemailProvider) + .apply(); + + // TODO(uabdullah): Check if we need to force move to the VM tab (e.g in the event of + // clicking a vm notification and a status wasn't yet fetched). } @Override @@ -812,6 +879,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen public void onActivityResume() { activityIsAlive = true; + registerVoicemailStatusContentObserver(context); callLogQueryHandler.fetchVoicemailStatus(); callLogQueryHandler.fetchMissedCallsUnreadCount(); // Reset the tab on resume to restart the timer @@ -820,6 +888,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen /** Should be called when {@link Activity#onStop()} is called. */ public void onActivityStop(boolean changingConfigurations, boolean keyguardLocked) { + context.getContentResolver().unregisterContentObserver(voicemailStatusObserver); activityIsAlive = false; if (viewedCallLogTabPastTimeThreshold() && !changingConfigurations && !keyguardLocked) { markMissedCallsAsReadAndRemoveNotification(); diff --git a/java/com/android/dialer/main/impl/bottomnav/BottomNavBar.java b/java/com/android/dialer/main/impl/bottomnav/BottomNavBar.java index d9a446f84..5ee33fc71 100644 --- a/java/com/android/dialer/main/impl/bottomnav/BottomNavBar.java +++ b/java/com/android/dialer/main/impl/bottomnav/BottomNavBar.java @@ -23,6 +23,7 @@ import android.util.AttributeSet; import android.view.View; import android.widget.LinearLayout; import com.android.dialer.common.Assert; +import com.android.dialer.common.LogUtil; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; @@ -123,8 +124,25 @@ public final class BottomNavBar extends LinearLayout { } } + /** + * Displays or hides the voicemail tab. + * + *

    In the event that the voicemail tab was earlier visible but is now no longer visible, we + * move to the speed dial tab. + * + * @param showTab whether to hide or show the voicemail + */ public void showVoicemail(boolean showTab) { + LogUtil.i("OldMainActivityPeer.showVoicemail", "showing Tab:%b", showTab); + int voicemailpreviousVisibility = voicemail.getVisibility(); voicemail.setVisibility(showTab ? View.VISIBLE : View.GONE); + int voicemailcurrentVisibility = voicemail.getVisibility(); + + if (voicemailpreviousVisibility != voicemailcurrentVisibility + && voicemailpreviousVisibility == View.VISIBLE) { + LogUtil.i("OldMainActivityPeer.showVoicemail", "hid VM tab and moved to speed dial tab"); + selectTab(TabIndex.SPEED_DIAL); + } } public void setNotificationCount(@TabIndex int tab, int count) { -- cgit v1.2.3 From c267ce51a7d5855661fbdb1b79cfd7aec88f9737 Mon Sep 17 00:00:00 2001 From: maxwelb Date: Wed, 28 Feb 2018 16:28:02 -0800 Subject: Add accessibility label for voicemail transcription rating Bug: 73788896 Test: Manual :/ PiperOrigin-RevId: 187401558 Change-Id: I1c2c08cc01fd38ad5820c454991473cfb8f0fc76 --- java/com/android/dialer/app/res/layout/call_log_list_item.xml | 2 ++ java/com/android/dialer/app/res/values/strings.xml | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/java/com/android/dialer/app/res/layout/call_log_list_item.xml b/java/com/android/dialer/app/res/layout/call_log_list_item.xml index 1b776b42c..acaa82085 100644 --- a/java/com/android/dialer/app/res/layout/call_log_list_item.xml +++ b/java/com/android/dialer/app/res/layout/call_log_list_item.xml @@ -202,6 +202,7 @@ android:id="@+id/voicemail_transcription_rating_good" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/description_rating_good" android:gravity="end|center_vertical" android:focusable="true" android:src="@drawable/quantum_ic_thumb_up_grey600_24"/> @@ -211,6 +212,7 @@ android:id="@+id/voicemail_transcription_rating_bad" android:layout_width="wrap_content" android:layout_height="wrap_content" + android:contentDescription="@string/description_rating_bad" android:gravity="end|center_vertical" android:focusable="true" android:src="@drawable/quantum_ic_thumb_down_grey600_24"/> diff --git a/java/com/android/dialer/app/res/values/strings.xml b/java/com/android/dialer/app/res/values/strings.xml index 5974f47fd..7332c31e3 100644 --- a/java/com/android/dialer/app/res/values/strings.xml +++ b/java/com/android/dialer/app/res/values/strings.xml @@ -706,6 +706,14 @@ Thanks for your feedback + + Like + + + Dislike + View -- cgit v1.2.3