Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3e98abd1 authored by Treehugger Robot's avatar Treehugger Robot Committed by Gerrit Code Review
Browse files

Merge "Wire up SpeedDial fragment with SpeedDialUiItemLoader."

parents 2bdb59f0 2bee0528
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -36,6 +36,7 @@ import com.android.dialer.precall.PreCallComponent;
import com.android.dialer.preferredsim.suggestion.SimSuggestionComponent;
import com.android.dialer.simulator.SimulatorComponent;
import com.android.dialer.spam.SpamComponent;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.android.dialer.storage.StorageComponent;
import com.android.dialer.strictmode.StrictModeComponent;
import com.android.incallui.calllocation.CallLocationComponent;
@@ -67,6 +68,7 @@ public interface BaseDialerRootComponent
        PhoneLookupDatabaseComponent.HasComponent,
        PhoneNumberGeoUtilComponent.HasComponent,
        PreCallComponent.HasComponent,
        UiItemLoaderComponent.HasComponent,
        SimSuggestionComponent.HasComponent,
        SimulatorComponent.HasComponent,
        SpamComponent.HasComponent,
+37 −45
Original line number Diff line number Diff line
@@ -17,13 +17,8 @@
package com.android.dialer.speeddial;

import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
@@ -31,8 +26,12 @@ import android.widget.FrameLayout;
import android.widget.QuickContactBadge;
import android.widget.TextView;
import com.android.dialer.common.Assert;
import com.android.dialer.contactphoto.ContactPhotoManager;
import com.android.dialer.lettertile.LetterTileDrawable;
import com.android.dialer.glidephotomanager.GlidePhotoManagerComponent;
import com.android.dialer.glidephotomanager.PhotoInfo;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import java.util.ArrayList;
import java.util.List;

/** ViewHolder for starred/favorite contacts in {@link SpeedDialFragment}. */
public class FavoritesViewHolder extends RecyclerView.ViewHolder
@@ -48,7 +47,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
  private boolean hasDefaultNumber;
  private boolean isVideoCall;
  private String number;
  private String lookupKey;
  private List<Channel> channels;

  public FavoritesViewHolder(View view, FavoriteContactsListener listener) {
    super(view);
@@ -62,44 +61,37 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
    this.listener = listener;
  }

  public void bind(Context context, Cursor cursor) {
    Assert.checkArgument(cursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1);
    isVideoCall = false; // TODO(calderwoodra): get from disambig data
    number = cursor.getString(StrequentContactsCursorLoader.PHONE_NUMBER);
  public void bind(Context context, SpeedDialUiItem speedDialUiItem) {
    Assert.checkArgument(speedDialUiItem.isStarred());

    String name = cursor.getString(StrequentContactsCursorLoader.PHONE_DISPLAY_NAME);
    long contactId = cursor.getLong(StrequentContactsCursorLoader.PHONE_ID);
    lookupKey = cursor.getString(StrequentContactsCursorLoader.PHONE_LOOKUP_KEY);
    Uri contactUri = Contacts.getLookupUri(contactId, lookupKey);

    String photoUri = cursor.getString(StrequentContactsCursorLoader.PHONE_PHOTO_URI);
    ContactPhotoManager.getInstance(context)
        .loadDialerThumbnailOrPhoto(
            photoView,
            contactUri,
            cursor.getLong(StrequentContactsCursorLoader.PHONE_PHOTO_ID),
            photoUri == null ? null : Uri.parse(photoUri),
            name,
            LetterTileDrawable.TYPE_DEFAULT);
    nameView.setText(name);
    phoneType.setText(getLabel(context.getResources(), cursor));
    nameView.setText(speedDialUiItem.name());
    hasDefaultNumber = speedDialUiItem.defaultChannel() != null;
    if (hasDefaultNumber) {
      channels = new ArrayList<>();
      isVideoCall = speedDialUiItem.defaultChannel().isVideoTechnology();
      number = speedDialUiItem.defaultChannel().number();
      phoneType.setText(speedDialUiItem.defaultChannel().label());
      videoCallIcon.setVisibility(isVideoCall ? View.VISIBLE : View.GONE);

    // TODO(calderwoodra): Update this to include communication avenues also
    hasDefaultNumber = cursor.getInt(StrequentContactsCursorLoader.PHONE_IS_SUPER_PRIMARY) != 0;
    } else {
      channels = speedDialUiItem.channels();
      isVideoCall = false;
      number = null;
      phoneType.setText("");
      videoCallIcon.setVisibility(View.GONE);
    }

  // TODO(calderwoodra): handle CNAP and cequint types.
  // TODO(calderwoodra): unify this into a utility method with CallLogAdapter#getNumberType
  private static String getLabel(Resources resources, Cursor cursor) {
    int numberType = cursor.getInt(StrequentContactsCursorLoader.PHONE_TYPE);
    String numberLabel = cursor.getString(StrequentContactsCursorLoader.PHONE_LABEL);

    // Returns empty label instead of "custom" if the custom label is empty.
    if (numberType == Phone.TYPE_CUSTOM && TextUtils.isEmpty(numberLabel)) {
      return "";
    }
    return (String) Phone.getTypeLabel(resources, numberType, numberLabel);
    GlidePhotoManagerComponent.get(context)
        .glidePhotoManager()
        .loadQuickContactBadge(
            photoView,
            PhotoInfo.newBuilder()
                .setPhotoId(speedDialUiItem.photoId())
                .setPhotoUri(speedDialUiItem.photoUri())
                .setName(speedDialUiItem.name())
                .setLookupUri(
                    Contacts.getLookupUri(speedDialUiItem.contactId(), speedDialUiItem.lookupKey())
                        .toString())
                .build());
  }

  @Override
@@ -107,7 +99,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
    if (hasDefaultNumber) {
      listener.onClick(number, isVideoCall);
    } else {
      listener.onAmbiguousContactClicked(lookupKey);
      listener.onAmbiguousContactClicked(channels);
    }
  }

@@ -122,7 +114,7 @@ public class FavoritesViewHolder extends RecyclerView.ViewHolder
  public interface FavoriteContactsListener {

    /** Called when the user clicks on a favorite contact that doesn't have a default number. */
    void onAmbiguousContactClicked(String contactId);
    void onAmbiguousContactClicked(List<Channel> channels);

    /** Called when the user clicks on a favorite contact. */
    void onClick(String number, boolean isVideoCall);
+84 −34
Original line number Diff line number Diff line
/*
 * Copyright (C) 2017 The Android Open Source Project
 * 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.
@@ -16,19 +16,30 @@

package com.android.dialer.speeddial;

import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build.VERSION_CODES;
import android.support.annotation.IntDef;
import android.support.annotation.NonNull;
import android.support.annotation.VisibleForTesting;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.GridLayoutManager.SpanSizeLookup;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.support.v7.widget.RecyclerView.ViewHolder;
import android.util.ArrayMap;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import com.android.dialer.common.Assert;
import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener;
import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
import com.android.dialer.speeddial.SpeedDialCursor.RowType;
import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * RecyclerView adapter for {@link SpeedDialFragment}.
@@ -42,14 +53,26 @@ import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListen
 *   <li>Suggested contacts
 * </ol>
 */
final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
@SuppressWarnings("AndroidApiChecker")
@TargetApi(VERSION_CODES.N)
public final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

  @Retention(RetentionPolicy.SOURCE)
  @IntDef({RowType.STARRED_HEADER, RowType.SUGGESTION_HEADER, RowType.STARRED, RowType.SUGGESTION})
  @interface RowType {
    int STARRED_HEADER = 0;
    int SUGGESTION_HEADER = 1;
    int STARRED = 2;
    int SUGGESTION = 3;
  }

  private final Context context;
  private final FavoriteContactsListener favoritesListener;
  private final SuggestedContactsListener suggestedListener;
  private final SpeedDialHeaderListener headerListener;

  private SpeedDialCursor cursor;
  private final Map<Integer, Integer> positionToRowTypeMap = new ArrayMap<>();
  private List<SpeedDialUiItem> speedDialUiItems;

  public SpeedDialAdapter(
      Context context,
@@ -64,39 +87,45 @@ final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde

  @Override
  public int getItemViewType(int position) {
    return cursor.getRowType(position);
    return positionToRowTypeMap.get(position);
  }

  @NonNull
  @Override
  public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
    LayoutInflater inflater = LayoutInflater.from(context);
    if (viewType == RowType.STARRED) {
    switch (viewType) {
      case RowType.STARRED:
        return new FavoritesViewHolder(
            inflater.inflate(R.layout.favorite_item_layout, parent, false), favoritesListener);
    } else if (viewType == RowType.SUGGESTION) {
      case RowType.SUGGESTION:
        return new SuggestionViewHolder(
            inflater.inflate(R.layout.suggestion_row_layout, parent, false), suggestedListener);
    } else if (viewType == RowType.HEADER) {
      case RowType.STARRED_HEADER:
      case RowType.SUGGESTION_HEADER:
        return new HeaderViewHolder(
            inflater.inflate(R.layout.speed_dial_header_layout, parent, false), headerListener);
    } else {
      default:
        throw Assert.createIllegalStateFailException("Invalid viewType: " + viewType);
    }
  }

  @Override
  public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
    cursor.moveToPosition(position);
    switch (cursor.getRowType(position)) {
      case RowType.HEADER:
        ((HeaderViewHolder) holder).setHeaderText(cursor.getHeader());
        ((HeaderViewHolder) holder).showAddButton(cursor.hasFavorites() && position == 0);
        break;
  public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
    switch (getItemViewType(position)) {
      case RowType.STARRED_HEADER:
        ((HeaderViewHolder) holder).setHeaderText(R.string.favorites_header);
        ((HeaderViewHolder) holder).showAddButton(true);
        return;
      case RowType.SUGGESTION_HEADER:
        ((HeaderViewHolder) holder).setHeaderText(R.string.suggestions_header);
        ((HeaderViewHolder) holder).showAddButton(false);
        return;
      case RowType.STARRED:
        ((FavoritesViewHolder) holder).bind(context, cursor);
        ((FavoritesViewHolder) holder).bind(context, speedDialUiItems.get(position - 1));
        break;
      case RowType.SUGGESTION:
        ((SuggestionViewHolder) holder).bind(context, cursor);
        ((SuggestionViewHolder) holder).bind(context, speedDialUiItems.get(position - 2));
        break;
      default:
        throw Assert.createIllegalStateFailException("Invalid view holder: " + holder);
@@ -105,15 +134,35 @@ final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde

  @Override
  public int getItemCount() {
    return cursor == null || cursor.isClosed() ? 0 : cursor.getCount();
    return positionToRowTypeMap.size();
  }

  public void setCursor(SpeedDialCursor cursor) {
    this.cursor = cursor;
    notifyDataSetChanged();
  public void setSpeedDialUiItems(List<SpeedDialUiItem> immutableSpeedDialUiItems) {
    speedDialUiItems = new ArrayList<>();
    speedDialUiItems.addAll(immutableSpeedDialUiItems);
    speedDialUiItems.sort((o1, o2) -> Boolean.compare(o2.isStarred(), o1.isStarred()));
    positionToRowTypeMap.clear();
    if (speedDialUiItems.isEmpty()) {
      return;
    }

    // Show the add favorites even if there are no favorite contacts
    positionToRowTypeMap.put(0, RowType.STARRED_HEADER);
    int positionOfSuggestionHeader = 1;
    for (int i = 0; i < speedDialUiItems.size(); i++) {
      if (speedDialUiItems.get(i).isStarred()) {
        positionToRowTypeMap.put(i + 1, RowType.STARRED); // +1 for the header
        positionOfSuggestionHeader++;
      } else {
        positionToRowTypeMap.put(i + 2, RowType.SUGGESTION); // +2 for both headers
      }
    }
    if (!speedDialUiItems.get(speedDialUiItems.size() - 1).isStarred()) {
      positionToRowTypeMap.put(positionOfSuggestionHeader, RowType.SUGGESTION_HEADER);
    }
  }

  LayoutManager getLayoutManager(Context context) {
  /* package-private */ LayoutManager getLayoutManager(Context context) {
    GridLayoutManager layoutManager = new GridLayoutManager(context, 3 /* spanCount */);
    layoutManager.setSpanSizeLookup(
        new SpanSizeLookup() {
@@ -127,15 +176,16 @@ final class SpeedDialAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde

  @VisibleForTesting
  int getSpanSize(int position) {
    switch (cursor.getRowType(position)) {
    switch (getItemViewType(position)) {
      case RowType.SUGGESTION:
      case RowType.HEADER:
      case RowType.STARRED_HEADER:
      case RowType.SUGGESTION_HEADER:
        return 3; // span the whole screen
      case RowType.STARRED:
        return 1; // span 1/3 of the screen
      default:
        throw Assert.createIllegalStateFailException(
            "Invalid row type: " + cursor.getRowType(position));
            "Invalid row type: " + positionToRowTypeMap.get(position));
    }
  }
}
+0 −148
Original line number Diff line number Diff line
/*
 * 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.speeddial;

import android.annotation.SuppressLint;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.support.annotation.IntDef;
import android.support.annotation.StringRes;
import com.android.dialer.common.Assert;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.ArrayList;
import java.util.List;

/** Cursor for favorites contacts. */
final class SpeedDialCursor extends MergeCursor {

  /**
   * Caps the speed dial list to contain at most 20 contacts, including favorites and suggestions.
   * It is only a soft limit though, for the case that there are more than 20 favorite contacts.
   */
  private static final int SPEED_DIAL_CONTACT_LIST_SOFT_LIMIT = 20;

  private static final String[] HEADER_CURSOR_PROJECTION = {"header"};
  private static final int HEADER_COLUMN_POSITION = 0;
  private boolean hasFavorites;

  @Retention(RetentionPolicy.SOURCE)
  @IntDef({RowType.HEADER, RowType.STARRED, RowType.SUGGESTION})
  @interface RowType {
    int HEADER = 0;
    int STARRED = 1;
    int SUGGESTION = 2;
  }

  public static SpeedDialCursor newInstance(Cursor strequentCursor) {
    if (strequentCursor == null || strequentCursor.getCount() == 0) {
      return null;
    }
    SpeedDialCursor cursor = new SpeedDialCursor(buildCursors(strequentCursor));
    strequentCursor.close();
    return cursor;
  }

  private static Cursor[] buildCursors(Cursor strequentCursor) {
    MatrixCursor starred = new MatrixCursor(StrequentContactsCursorLoader.PHONE_PROJECTION);
    MatrixCursor suggestions = new MatrixCursor(StrequentContactsCursorLoader.PHONE_PROJECTION);

    strequentCursor.moveToPosition(-1);
    while (strequentCursor.moveToNext()) {
      if (strequentCursor.getPosition() != 0) {
        long contactId = strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID);
        int position = strequentCursor.getPosition();
        boolean duplicate = false;
        // Iterate backwards through the cursor to check that this isn't a duplicate contact
        // TODO(calderwoodra): improve this algorithm (currently O(n^2)).
        while (strequentCursor.moveToPrevious() && !duplicate) {
          duplicate |=
              strequentCursor.getLong(StrequentContactsCursorLoader.PHONE_CONTACT_ID) == contactId;
        }
        strequentCursor.moveToPosition(position);
        if (duplicate) {
          continue;
        }
      }

      if (strequentCursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1) {
        StrequentContactsCursorLoader.addToCursor(starred, strequentCursor);
      } else if (starred.getCount() + suggestions.getCount() < SPEED_DIAL_CONTACT_LIST_SOFT_LIMIT) {
        // Since all starred contacts come before each non-starred contact, it's safe to assume that
        // this list will never exceed the soft limit unless there are more starred contacts than
        // the limit permits.
        StrequentContactsCursorLoader.addToCursor(suggestions, strequentCursor);
      }
    }

    List<Cursor> cursorList = new ArrayList<>();
    if (starred.getCount() > 0) {
      cursorList.add(createHeaderCursor(R.string.favorites_header));
      cursorList.add(starred);
    }
    if (suggestions.getCount() > 0) {
      cursorList.add(createHeaderCursor(R.string.suggestions_header));
      cursorList.add(suggestions);
    }
    return cursorList.toArray(new Cursor[cursorList.size()]);
  }

  private static Cursor createHeaderCursor(@StringRes int header) {
    MatrixCursor cursor = new MatrixCursor(HEADER_CURSOR_PROJECTION);
    cursor.newRow().add(HEADER_CURSOR_PROJECTION[HEADER_COLUMN_POSITION], header);
    return cursor;
  }

  @RowType
  int getRowType(int position) {
    moveToPosition(position);
    if (getColumnCount() == 1) {
      return RowType.HEADER;
    } else if (getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1) {
      return RowType.STARRED;
    } else {
      return RowType.SUGGESTION;
    }
  }

  @SuppressLint("DefaultLocale")
  @StringRes
  int getHeader() {
    if (getRowType(getPosition()) != RowType.HEADER) {
      throw Assert.createIllegalStateFailException(
          String.format("Current position (%d) is not a header.", getPosition()));
    }
    return getInt(HEADER_COLUMN_POSITION);
  }

  public boolean hasFavorites() {
    return hasFavorites;
  }

  private SpeedDialCursor(Cursor[] cursors) {
    super(cursors);
    for (Cursor cursor : cursors) {
      cursor.moveToFirst();
      if (cursor.getColumnCount() != 1
          && cursor.getInt(StrequentContactsCursorLoader.PHONE_STARRED) == 1) {
        hasFavorites = true;
        break;
      }
    }
  }
}
+33 −37
Original line number Diff line number Diff line
@@ -17,23 +17,28 @@
package com.android.dialer.speeddial;

import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.android.dialer.callintent.CallInitiationType;
import com.android.dialer.callintent.CallIntentBuilder;
import com.android.dialer.common.Assert;
import com.android.dialer.precall.PreCall;
import com.android.dialer.speeddial.FavoritesViewHolder.FavoriteContactsListener;
import com.android.dialer.speeddial.HeaderViewHolder.SpeedDialHeaderListener;
import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListener;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
import com.android.dialer.speeddial.loader.UiItemLoaderComponent;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.MoreExecutors;
import java.util.List;

/**
 * Fragment for displaying:
@@ -47,13 +52,9 @@ import com.android.dialer.speeddial.SuggestionViewHolder.SuggestedContactsListen
 */
public class SpeedDialFragment extends Fragment {

  private static final int STREQUENT_CONTACTS_LOADER_ID = 1;

  private final SpeedDialHeaderListener headerListener = new SpeedDialFragmentHeaderListener();
  private final FavoriteContactsListener favoritesListener = new SpeedDialFavoritesListener();
  private final SuggestedContactsListener suggestedListener = new SpeedDialSuggestedListener();
  private final SpeedDialFragmentLoaderCallback loaderCallback =
      new SpeedDialFragmentLoaderCallback();

  private SpeedDialAdapter adapter;

@@ -72,7 +73,6 @@ public class SpeedDialFragment extends Fragment {
        new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener);
    recyclerView.setLayoutManager(adapter.getLayoutManager(getContext()));
    recyclerView.setAdapter(adapter);
    getLoaderManager().initLoader(STREQUENT_CONTACTS_LOADER_ID, null /* args */, loaderCallback);
    return view;
  }

@@ -84,7 +84,28 @@ public class SpeedDialFragment extends Fragment {
  @Override
  public void onResume() {
    super.onResume();
    getLoaderManager().restartLoader(STREQUENT_CONTACTS_LOADER_ID, null, loaderCallback);
    Futures.addCallback(
        UiItemLoaderComponent.get(getContext().getApplicationContext())
            .speedDialUiItemLoader()
            .loadSpeedDialUiItems(),
        new FutureCallback<List<SpeedDialUiItem>>() {
          @Override
          public void onSuccess(List<SpeedDialUiItem> speedDialUiItems) {
            // TODO(calderwoodra): this is bad
            new Handler(Looper.getMainLooper())
                .post(
                    () -> {
                      adapter.setSpeedDialUiItems(speedDialUiItems);
                      adapter.notifyDataSetChanged();
                    });
          }

          @Override
          public void onFailure(Throwable throwable) {
            throw new RuntimeException(throwable);
          }
        },
        MoreExecutors.directExecutor());
  }

  private class SpeedDialFragmentHeaderListener implements SpeedDialHeaderListener {
@@ -98,8 +119,8 @@ public class SpeedDialFragment extends Fragment {
  private class SpeedDialFavoritesListener implements FavoriteContactsListener {

    @Override
    public void onAmbiguousContactClicked(String lookupKey) {
      DisambigDialog.show(lookupKey, getFragmentManager());
    public void onAmbiguousContactClicked(List<Channel> channels) {
      // TODO(calderwoodra): implement the disambig dialog with channels
    }

    @Override
@@ -130,29 +151,4 @@ public class SpeedDialFragment extends Fragment {
          getContext(), new CallIntentBuilder(number, CallInitiationType.Type.SPEED_DIAL));
    }
  }

  /**
   * Loader callback that registers a content observer. {@link #unregisterContentObserver()} needs
   * to be called during tear down of the fragment.
   */
  private class SpeedDialFragmentLoaderCallback implements LoaderCallbacks<Cursor> {

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
      if (id == STREQUENT_CONTACTS_LOADER_ID) {
        return new StrequentContactsCursorLoader(getContext());
      }
      throw Assert.createIllegalStateFailException("Invalid loader id: " + id);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
      adapter.setCursor((SpeedDialCursor) data);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
      adapter.setCursor(null);
    }
  }
}
Loading