Merge changes Id16ea475,I38997710 am: 9da84f472f
am: 2f95509942

Change-Id: I1dbdb2ae4f3ede1d00b3533135e781fef01028de
diff --git a/assets/quantum/res/drawable/quantum_ic_schedule_vd_theme_24.xml b/assets/quantum/res/drawable/quantum_ic_schedule_vd_theme_24.xml
new file mode 100644
index 0000000..54fd545
--- /dev/null
+++ b/assets/quantum/res/drawable/quantum_ic_schedule_vd_theme_24.xml
@@ -0,0 +1,25 @@
+<!--
+  ~ Copyright (C) 2018 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
+  -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0"
+        android:tint="?attr/colorControlNormal">
+    <path
+        android:fillColor="@android:color/white"
+        android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7L11,7v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z"/>
+</vector>
diff --git a/java/com/android/dialer/database/CallLogQueryHandler.java b/java/com/android/dialer/database/CallLogQueryHandler.java
index 1aa1251..92c49a0 100644
--- a/java/com/android/dialer/database/CallLogQueryHandler.java
+++ b/java/com/android/dialer/database/CallLogQueryHandler.java
@@ -40,6 +40,7 @@
 import com.android.dialer.phonenumbercache.CallLogQuery;
 import com.android.dialer.telecom.TelecomUtil;
 import com.android.dialer.util.PermissionsUtil;
+import com.android.dialer.voicemailstatus.VoicemailStatusQuery;
 import com.android.voicemail.VoicemailComponent;
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
index 05a3bc9..044d8df 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailAdapter.java
@@ -25,7 +25,6 @@
 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;
@@ -49,10 +48,9 @@
 import com.android.dialer.voicemail.listui.error.VoicemailErrorMessageCreator;
 import com.android.dialer.voicemail.listui.error.VoicemailStatus;
 import com.android.dialer.voicemail.model.VoicemailEntry;
+import com.google.common.collect.ImmutableList;
 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;
@@ -74,7 +72,6 @@
   }
 
   private Cursor cursor;
-  private Cursor voicemailStatusCursor;
   private final Clock clock;
   private final GlidePhotoManager glidePhotoManager;
 
@@ -880,6 +877,7 @@
       new OnErrorListener() {
         @Override
         public boolean onError(MediaPlayer mp, int what, int extra) {
+          LogUtil.e("NewVoicemailAdapter.onError", "onError, what:%d, extra:%d", what, extra);
           Assert.checkArgument(
               mediaPlayer.getMediaPlayer().equals(mp),
               "there should always only be one instance of the media player");
@@ -1009,36 +1007,24 @@
     }
   }
 
-  @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
-  public void setVoicemailStatusCursor(Cursor voicemailStatusCursor) {
-    this.voicemailStatusCursor = voicemailStatusCursor;
-  }
+  /**
+   * Updates the voicemail alert message to reflect the state of the {@link VoicemailStatus} table.
+   * TODO(uabdullah): Handle ToS properly (a bug)
+   */
+  public void updateVoicemailAlertWithMostRecentStatus(
+      Context context, ImmutableList<VoicemailStatus> voicemailStatuses) {
 
-  // TODO(uabdullah): Handle ToS properly
-  public void updateAlert(Context context) {
-    if (voicemailStatusCursor == null) {
-      LogUtil.i("NewVoicemailAdapter.updateAlert", "status cursor was null");
+    if (voicemailStatuses.isEmpty()) {
+      LogUtil.i(
+          "NewVoicemailAdapter.updateVoicemailAlertWithMostRecentStatus",
+          "voicemailStatuses was empty");
       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) {
+    for (VoicemailStatus status : voicemailStatuses) {
       voicemailErrorMessage = messageCreator.create(context, status, null);
       if (voicemailErrorMessage != null) {
         break;
@@ -1046,6 +1032,7 @@
     }
 
     if (voicemailErrorMessage != null) {
+      LogUtil.i("NewVoicemailAdapter.updateVoicemailAlertWithMostRecentStatus", "showing alert");
       voicemailAlertPosition = 0;
       updateHeaderPositions();
       notifyItemChanged(0);
diff --git a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
index 45a5443..8b6fcbc 100644
--- a/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
+++ b/java/com/android/dialer/voicemail/listui/NewVoicemailFragment.java
@@ -16,8 +16,10 @@
 
 package com.android.dialer.voicemail.listui;
 
+import android.content.Context;
 import android.database.Cursor;
 import android.os.Bundle;
+import android.provider.VoicemailContract.Status;
 import android.support.annotation.Nullable;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.LoaderManager.LoaderCallbacks;
@@ -35,10 +37,14 @@
 import com.android.dialer.common.concurrent.DialerExecutorComponent;
 import com.android.dialer.common.concurrent.ThreadUtil;
 import com.android.dialer.common.concurrent.UiListener;
-import com.android.dialer.database.CallLogQueryHandler;
-import com.android.dialer.database.CallLogQueryHandler.Listener;
 import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
+import com.android.dialer.voicemail.listui.error.VoicemailStatus;
+import com.android.dialer.voicemailstatus.VoicemailStatusQuery;
+import com.android.voicemail.VoicemailComponent;
+import com.google.common.collect.ImmutableList;
 import com.google.common.util.concurrent.ListenableFuture;
+import java.util.ArrayList;
+import java.util.List;
 
 // TODO(uabdullah): Register content observer for VoicemailContract.Status.CONTENT_URI in onStart
 /** Fragment for Dialer Voicemail Tab. */
@@ -57,8 +63,9 @@
   private UiListener<Void> refreshAnnotatedCallLogListener;
   @Nullable private Runnable refreshAnnotatedCallLogRunnable;
 
+  private UiListener<ImmutableList<VoicemailStatus>> queryVoicemailStatusTableListener;
+
   private RecyclerView recyclerView;
-  private CallLogQueryHandler callLogQueryHandler;
 
   public NewVoicemailFragment() {
     LogUtil.enterBlock("NewVoicemailFragment.NewVoicemailFragment");
@@ -79,6 +86,13 @@
         DialerExecutorComponent.get(getContext())
             .createUiListener(
                 getActivity().getFragmentManager(), "NewVoicemailFragment.refreshAnnotatedCallLog");
+
+    queryVoicemailStatusTableListener =
+        DialerExecutorComponent.get(getContext())
+            .createUiListener(
+                getActivity().getFragmentManager(),
+                "NewVoicemailFragment.queryVoicemailStatusTable");
+
     refreshAnnotatedCallLogWorker = component.getRefreshAnnotatedCallLogWorker();
   }
 
@@ -192,31 +206,73 @@
       ((NewVoicemailAdapter) recyclerView.getAdapter()).updateCursor(data);
       ((NewVoicemailAdapter) recyclerView.getAdapter()).checkAndPlayVoicemail();
     }
-    callLogQueryHandler =
-        new CallLogQueryHandler(
-            getContext(), getContext().getContentResolver(), new NewVoicemailFragmentListener());
-    callLogQueryHandler.fetchVoicemailStatus();
+
+    queryAndUpdateVoicemailStatusAlert();
   }
 
-  private final class NewVoicemailFragmentListener implements Listener {
+  private void queryAndUpdateVoicemailStatusAlert() {
+    queryVoicemailStatusTableListener.listen(
+        getContext(),
+        queryVoicemailStatus(getContext()),
+        this::updateVoicemailStatusAlert,
+        throwable -> {
+          throw new RuntimeException(throwable);
+        });
+  }
 
-    @Override
-    public void onVoicemailStatusFetched(Cursor statusCursor) {
-      LogUtil.enterBlock("NewVoicemailFragmentListener.onVoicemailStatusFetched");
-      ((NewVoicemailAdapter) recyclerView.getAdapter()).setVoicemailStatusCursor(statusCursor);
-      ((NewVoicemailAdapter) recyclerView.getAdapter()).updateAlert(getContext());
-    }
+  private ListenableFuture<ImmutableList<VoicemailStatus>> queryVoicemailStatus(Context context) {
+    return DialerExecutorComponent.get(context)
+        .backgroundExecutor()
+        .submit(
+            () -> {
+              StringBuilder where = new StringBuilder();
+              List<String> selectionArgs = new ArrayList<>();
 
-    @Override
-    public void onVoicemailUnreadCountFetched(Cursor cursor) {}
+              VoicemailComponent.get(context)
+                  .getVoicemailClient()
+                  .appendOmtpVoicemailStatusSelectionClause(context, where, selectionArgs);
 
-    @Override
-    public void onMissedCallsUnreadCountFetched(Cursor cursor) {}
+              ImmutableList.Builder<VoicemailStatus> statuses = ImmutableList.builder();
 
-    @Override
-    public boolean onCallsFetched(Cursor combinedCursor) {
-      return false;
-    }
+              try (Cursor cursor =
+                  context
+                      .getContentResolver()
+                      .query(
+                          Status.CONTENT_URI,
+                          VoicemailStatusQuery.getProjection(),
+                          where.toString(),
+                          selectionArgs.toArray(new String[selectionArgs.size()]),
+                          null)) {
+                if (cursor == null) {
+                  LogUtil.e(
+                      "NewVoicemailFragment.queryVoicemailStatus", "query failed. Null cursor.");
+                  return statuses.build();
+                }
+
+                LogUtil.i(
+                    "NewVoicemailFragment.queryVoicemailStatus",
+                    "cursor size:%d ",
+                    cursor.getCount());
+
+                while (cursor.moveToNext()) {
+                  VoicemailStatus status = new VoicemailStatus(context, cursor);
+                  if (status.isActive()) {
+                    statuses.add(status);
+                    // TODO(a bug): Handle Service State Listeners
+                  }
+                }
+              }
+              LogUtil.i(
+                  "NewVoicemailFragment.queryVoicemailStatus",
+                  "query returned %d results",
+                  statuses.build().size());
+              return statuses.build();
+            });
+  }
+
+  private void updateVoicemailStatusAlert(ImmutableList<VoicemailStatus> voicemailStatuses) {
+    ((NewVoicemailAdapter) recyclerView.getAdapter())
+        .updateVoicemailAlertWithMostRecentStatus(getContext(), voicemailStatuses);
   }
 
   @Override
diff --git a/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java b/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java
index 3447f03..9b7b7fd 100644
--- a/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java
+++ b/java/com/android/dialer/voicemail/listui/error/VoicemailStatus.java
@@ -33,7 +33,7 @@
 import android.telephony.TelephonyManager;
 import android.text.TextUtils;
 import com.android.dialer.common.LogUtil;
-import com.android.dialer.database.VoicemailStatusQuery;
+import com.android.dialer.voicemailstatus.VoicemailStatusQuery;
 
 /** Structured data from {@link android.provider.VoicemailContract.Status} */
 public class VoicemailStatus {
diff --git a/java/com/android/dialer/voicemail/listui/error/VoicemailStatusWorker.java b/java/com/android/dialer/voicemail/listui/error/VoicemailStatusWorker.java
index 20e46ee..df58d41 100644
--- a/java/com/android/dialer/voicemail/listui/error/VoicemailStatusWorker.java
+++ b/java/com/android/dialer/voicemail/listui/error/VoicemailStatusWorker.java
@@ -23,8 +23,8 @@
 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.dialer.voicemailstatus.VoicemailStatusQuery;
 import com.android.voicemail.VoicemailComponent;
 import java.util.ArrayList;
 import java.util.List;
diff --git a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java b/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java
index 313fc1b..16a8c7b 100644
--- a/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java
+++ b/java/com/android/dialer/voicemailstatus/VoicemailStatusHelper.java
@@ -18,7 +18,6 @@
 
 import android.database.Cursor;
 import android.provider.VoicemailContract.Status;
-import com.android.dialer.database.VoicemailStatusQuery;
 
 /**
  * Utility used by the call log UI to determine what user message, if any, related to voicemail
diff --git a/java/com/android/dialer/database/VoicemailStatusQuery.java b/java/com/android/dialer/voicemailstatus/VoicemailStatusQuery.java
similarity index 98%
rename from java/com/android/dialer/database/VoicemailStatusQuery.java
rename to java/com/android/dialer/voicemailstatus/VoicemailStatusQuery.java
index dbd88be..4a6e9f7 100644
--- a/java/com/android/dialer/database/VoicemailStatusQuery.java
+++ b/java/com/android/dialer/voicemailstatus/VoicemailStatusQuery.java
@@ -14,7 +14,7 @@
  * limitations under the License
  */
 
-package com.android.dialer.database;
+package com.android.dialer.voicemailstatus;
 
 import android.os.Build.VERSION;
 import android.os.Build.VERSION_CODES;