summaryrefslogtreecommitdiff
path: root/java/com/android/dialer
diff options
context:
space:
mode:
Diffstat (limited to 'java/com/android/dialer')
-rw-r--r--java/com/android/dialer/logging/dialer_impression.proto11
-rw-r--r--java/com/android/dialer/main/impl/OldMainActivityPeer.java14
-rw-r--r--java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java9
-rw-r--r--java/com/android/dialer/speeddial/ContextMenu.java44
-rw-r--r--java/com/android/dialer/speeddial/SpeedDialFragment.java90
-rw-r--r--java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java101
-rw-r--r--java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java80
7 files changed, 218 insertions, 131 deletions
diff --git a/java/com/android/dialer/logging/dialer_impression.proto b/java/com/android/dialer/logging/dialer_impression.proto
index 7cd22079c..55cef9a38 100644
--- a/java/com/android/dialer/logging/dialer_impression.proto
+++ b/java/com/android/dialer/logging/dialer_impression.proto
@@ -12,7 +12,7 @@ message DialerImpression {
// Event enums to be used for Impression Logging in Dialer.
// It's perfectly acceptable for this enum to be large
// Values should be from 1000 to 100000.
- // Next Tag: 1392
+ // Next Tag: 1397
enum Type {
UNKNOWN_AOSP_EVENT_TYPE = 1000;
@@ -770,5 +770,14 @@ message DialerImpression {
// Send button clicked in RTT call, this includes send button on keyboard.
RTT_SEND_BUTTON_CLICKED = 1387;
RTT_KEYBOARD_SEND_BUTTON_CLICKED = 1388;
+
+ // For background calling
+ START_CALL_IN_BUBBLE_MODE = 1392;
+
+ // Switch audio route
+ IN_CALL_SWITCH_AUDIO_ROUTE_SPEAKER = 1393;
+ IN_CALL_SWITCH_AUDIO_ROUTE_WIRED_HEADSET = 1394;
+ IN_CALL_SWITCH_AUDIO_ROUTE_EARPIECE = 1395;
+ IN_CALL_SWITCH_AUDIO_ROUTE_BLUETOOTH = 1396;
}
}
diff --git a/java/com/android/dialer/main/impl/OldMainActivityPeer.java b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
index 9ac351094..e3d42fa9e 100644
--- a/java/com/android/dialer/main/impl/OldMainActivityPeer.java
+++ b/java/com/android/dialer/main/impl/OldMainActivityPeer.java
@@ -457,6 +457,7 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen
return DialpadFragment.isAddCallMode(intent);
}
+ @SuppressLint("MissingPermission")
@Override
public void onActivityResume() {
callLogFragmentListener.onActivityResume();
@@ -492,11 +493,16 @@ public class OldMainActivityPeer implements MainActivityPeer, FragmentUtilListen
bottomNavTabListener.ensureCorrectCallLogShown();
bottomNavTabListener.ensureCorrectVoicemailShown();
+ // Config the badge of missed calls for the new call log.
if (bottomNavTabListener.newCallLogFragmentActive()) {
- missedCallCountObserver.onChange(false); // Set the initial value for the badge
- activity
- .getContentResolver()
- .registerContentObserver(Calls.CONTENT_URI, true, missedCallCountObserver);
+ if (PermissionsUtil.hasCallLogReadPermissions(activity)) {
+ missedCallCountObserver.onChange(false); // Set the initial value for the badge
+ activity
+ .getContentResolver()
+ .registerContentObserver(Calls.CONTENT_URI, true, missedCallCountObserver);
+ } else {
+ bottomNav.setNotificationCount(TabIndex.CALL_LOG, 0);
+ }
}
// add 1 sec delay to get memory snapshot so that dialer wont react slowly on resume.
diff --git a/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java b/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java
index ee7f6d006..a4995c1e6 100644
--- a/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java
+++ b/java/com/android/dialer/main/impl/bottomnav/MissedCallCountObserver.java
@@ -16,15 +16,15 @@
package com.android.dialer.main.impl.bottomnav;
-import android.annotation.SuppressLint;
+import android.Manifest;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.provider.CallLog.Calls;
+import android.support.annotation.RequiresPermission;
import com.android.dialer.common.concurrent.DialerExecutorComponent;
import com.android.dialer.common.concurrent.UiListener;
import com.android.dialer.main.impl.bottomnav.BottomNavBar.TabIndex;
-import com.android.dialer.util.PermissionsUtil;
import com.google.common.util.concurrent.ListenableFuture;
/**
@@ -45,7 +45,7 @@ public final class MissedCallCountObserver extends ContentObserver {
this.uiListener = uiListener;
}
- @SuppressLint("MissingPermission")
+ @RequiresPermission(Manifest.permission.READ_CALL_LOG)
@Override
public void onChange(boolean selfChange) {
ListenableFuture<Integer> countFuture =
@@ -53,9 +53,6 @@ public final class MissedCallCountObserver extends ContentObserver {
.backgroundExecutor()
.submit(
() -> {
- if (!PermissionsUtil.hasCallLogReadPermissions(appContext)) {
- return 0;
- }
try (Cursor cursor =
appContext
.getContentResolver()
diff --git a/java/com/android/dialer/speeddial/ContextMenu.java b/java/com/android/dialer/speeddial/ContextMenu.java
index 126373c12..09505ab99 100644
--- a/java/com/android/dialer/speeddial/ContextMenu.java
+++ b/java/com/android/dialer/speeddial/ContextMenu.java
@@ -18,10 +18,12 @@ package com.android.dialer.speeddial;
import android.content.Context;
import android.support.annotation.Nullable;
+import android.support.annotation.VisibleForTesting;
import android.util.AttributeSet;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
+import com.android.dialer.common.Assert;
import com.android.dialer.speeddial.database.SpeedDialEntry.Channel;
import com.android.dialer.speeddial.loader.SpeedDialUiItem;
@@ -30,13 +32,13 @@ public class ContextMenu extends LinearLayout {
private ContextMenuItemListener listener;
+ private TextView voiceView;
private TextView videoView;
private TextView smsView;
private SpeedDialUiItem speedDialUiItem;
private Channel voiceChannel;
private Channel videoChannel;
- private Channel smsChannel;
public ContextMenu(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
@@ -50,9 +52,11 @@ public class ContextMenu extends LinearLayout {
videoView.setOnClickListener(v -> placeVideoCall());
smsView = findViewById(R.id.send_message_container);
- smsView.setOnClickListener(v -> listener.openSmsConversation(smsChannel.number()));
+ smsView.setOnClickListener(v -> listener.openSmsConversation(voiceChannel.number()));
+
+ voiceView = findViewById(R.id.voice_call_container);
+ voiceView.setOnClickListener(v -> placeVoiceCall());
- findViewById(R.id.voice_call_container).setOnClickListener(v -> placeVoiceCall());
findViewById(R.id.remove_container)
.setOnClickListener(v -> listener.removeFavoriteContact(speedDialUiItem));
findViewById(R.id.contact_info_container)
@@ -76,14 +80,11 @@ public class ContextMenu extends LinearLayout {
setX((float) (childLocation[0] + .5 * childLayout.getWidth() - .5 * getWidth()));
setY(childLocation[1] - parentLocation[1] + childLayout.getHeight());
- voiceChannel = speedDialUiItem.getDeterministicVoiceChannel();
- videoChannel = speedDialUiItem.getDeterministicVideoChannel();
- videoView.setVisibility(
- videoChannel == null && !speedDialUiItem.hasVideoChannels() ? View.GONE : View.VISIBLE);
-
- // TODO(calderwoodra): disambig dialog for texts?
- smsChannel = voiceChannel;
- smsView.setVisibility(smsChannel == null ? View.GONE : View.VISIBLE);
+ voiceChannel = speedDialUiItem.getDefaultVoiceChannel();
+ videoChannel = speedDialUiItem.getDefaultVideoChannel();
+ voiceView.setVisibility(videoChannel == null ? View.GONE : View.VISIBLE);
+ videoView.setVisibility(videoChannel == null ? View.GONE : View.VISIBLE);
+ smsView.setVisibility(voiceChannel == null ? View.GONE : View.VISIBLE);
// TODO(calderwoodra): a11y
// TODO(calderwoodra): animate this similar to the bubble menu
@@ -102,19 +103,11 @@ public class ContextMenu extends LinearLayout {
}
private void placeVoiceCall() {
- if (voiceChannel == null) {
- listener.disambiguateCall(speedDialUiItem);
- } else {
- listener.placeCall(voiceChannel);
- }
+ listener.placeCall(Assert.isNotNull(voiceChannel));
}
private void placeVideoCall() {
- if (videoChannel == null) {
- listener.disambiguateCall(speedDialUiItem);
- } else {
- listener.placeCall(videoChannel);
- }
+ listener.placeCall(Assert.isNotNull(videoChannel));
}
public boolean isVisible() {
@@ -122,19 +115,12 @@ public class ContextMenu extends LinearLayout {
}
/** Listener to report user clicks on menu items. */
+ @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE)
public interface ContextMenuItemListener {
/** Called when the user selects "voice call" or "video call" option from the context menu. */
void placeCall(Channel channel);
- /**
- * Called when the user selects "voice call" or "video call" option from the context menu, but
- * it's not clear which channel they want to call.
- *
- * <p>TODO(calderwoodra): discuss with product how we want to handle these cases
- */
- void disambiguateCall(SpeedDialUiItem speedDialUiItem);
-
/** Called when the user selects "send message" from the context menu. */
void openSmsConversation(String number);
diff --git a/java/com/android/dialer/speeddial/SpeedDialFragment.java b/java/com/android/dialer/speeddial/SpeedDialFragment.java
index 018f97888..97a5facab 100644
--- a/java/com/android/dialer/speeddial/SpeedDialFragment.java
+++ b/java/com/android/dialer/speeddial/SpeedDialFragment.java
@@ -105,6 +105,10 @@ public class SpeedDialFragment extends Fragment {
LogUtil.enterBlock("SpeedDialFragment.onCreateView");
View rootLayout = inflater.inflate(R.layout.fragment_speed_dial, container, false);
+ speedDialLoaderListener =
+ DialerExecutorComponent.get(getContext())
+ .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener");
+
// Setup favorite contact context menu
contextMenu = rootLayout.findViewById(R.id.favorite_contact_context_menu);
contextMenuBackground = rootLayout.findViewById(R.id.context_menu_background);
@@ -124,7 +128,10 @@ public class SpeedDialFragment extends Fragment {
rootLayout,
contextMenu,
contextMenuBackground,
- new SpeedDialContextMenuItemListener(getActivity(), getChildFragmentManager()),
+ new SpeedDialContextMenuItemListener(
+ getActivity(),
+ new UpdateSpeedDialAdapterListener(),
+ speedDialLoaderListener),
layoutManager);
adapter =
new SpeedDialAdapter(getContext(), favoritesListener, suggestedListener, headerListener);
@@ -138,10 +145,6 @@ public class SpeedDialFragment extends Fragment {
ItemTouchHelper touchHelper = new ItemTouchHelper(callback);
touchHelper.attachToRecyclerView(recyclerView);
adapter.setItemTouchHelper(touchHelper);
-
- speedDialLoaderListener =
- DialerExecutorComponent.get(getContext())
- .createUiListener(getChildFragmentManager(), "speed_dial_loader_listener");
return rootLayout;
}
@@ -317,19 +320,17 @@ public class SpeedDialFragment extends Fragment {
Channel defaultChannel = speedDialUiItem.defaultChannel();
// Add voice call module
- Channel voiceChannel = speedDialUiItem.getDeterministicVoiceChannel();
+ Channel voiceChannel = speedDialUiItem.getDefaultVoiceChannel();
if (voiceChannel != null) {
modules.add(
IntentModule.newCallModule(
getContext(),
new CallIntentBuilder(voiceChannel.number(), CallInitiationType.Type.SPEED_DIAL)
.setAllowAssistedDial(true)));
- } else {
- modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ false));
}
// Add video if we can determine the correct channel
- Channel videoChannel = speedDialUiItem.getDeterministicVideoChannel();
+ Channel videoChannel = speedDialUiItem.getDefaultVideoChannel();
if (videoChannel != null) {
modules.add(
IntentModule.newCallModule(
@@ -337,8 +338,6 @@ public class SpeedDialFragment extends Fragment {
new CallIntentBuilder(videoChannel.number(), CallInitiationType.Type.SPEED_DIAL)
.setIsVideoCall(true)
.setAllowAssistedDial(true)));
- } else if (speedDialUiItem.hasVideoChannels()) {
- modules.add(new DisambigDialogModule(speedDialUiItem, /* isVideo = */ true));
}
// Add sms module
@@ -396,58 +395,21 @@ public class SpeedDialFragment extends Fragment {
return false;
}
}
-
- private final class DisambigDialogModule implements HistoryItemActionModule {
-
- private final SpeedDialUiItem speedDialUiItem;
- private final boolean isVideo;
-
- DisambigDialogModule(SpeedDialUiItem speedDialUiItem, boolean isVideo) {
- this.speedDialUiItem = speedDialUiItem;
- this.isVideo = isVideo;
- }
-
- @Override
- public int getStringId() {
- if (isVideo) {
- return R.string.contact_menu_video_call;
- } else {
- return R.string.contact_menu_voice_call;
- }
- }
-
- @Override
- public int getDrawableId() {
- if (isVideo) {
- return R.drawable.quantum_ic_videocam_vd_theme_24;
- } else {
- return R.drawable.quantum_ic_phone_vd_theme_24;
- }
- }
-
- @Override
- public boolean onClick() {
- DisambigDialog.show(speedDialUiItem, getChildFragmentManager());
- return true;
- }
- }
}
private static final class SpeedDialContextMenuItemListener implements ContextMenuItemListener {
private final FragmentActivity activity;
- private final FragmentManager childFragmentManager;
+ private final SupportUiListener<ImmutableList<SpeedDialUiItem>> speedDialLoaderListener;
+ private final UpdateSpeedDialAdapterListener updateAdapterListener;
SpeedDialContextMenuItemListener(
- FragmentActivity activity, FragmentManager childFragmentManager) {
+ FragmentActivity activity,
+ UpdateSpeedDialAdapterListener updateAdapterListener,
+ SupportUiListener<ImmutableList<SpeedDialUiItem>> speedDialLoaderListener) {
this.activity = activity;
- this.childFragmentManager = childFragmentManager;
- }
-
- @Override
- public void disambiguateCall(SpeedDialUiItem speedDialUiItem) {
- // TODO(calderwoodra): show only video or voice channels in the disambig dialog
- DisambigDialog.show(speedDialUiItem, childFragmentManager);
+ this.updateAdapterListener = updateAdapterListener;
+ this.speedDialLoaderListener = speedDialLoaderListener;
}
@Override
@@ -472,7 +434,15 @@ public class SpeedDialFragment extends Fragment {
@Override
public void removeFavoriteContact(SpeedDialUiItem speedDialUiItem) {
- // TODO(calderwoodra): implement remove
+ speedDialLoaderListener.listen(
+ activity,
+ UiItemLoaderComponent.get(activity)
+ .speedDialUiItemMutator()
+ .removeSpeedDialUiItem(speedDialUiItem),
+ updateAdapterListener::updateAdapter,
+ throwable -> {
+ throw new RuntimeException(throwable);
+ });
}
@Override
@@ -485,6 +455,14 @@ public class SpeedDialFragment extends Fragment {
}
}
+ /** Listener for when a SpeedDialUiItem is updated. */
+ private class UpdateSpeedDialAdapterListener {
+
+ void updateAdapter(ImmutableList<SpeedDialUiItem> speedDialUiItems) {
+ onSpeedDialUiItemListLoaded(speedDialUiItems);
+ }
+ }
+
/** Interface for {@link SpeedDialFragment} to communicate with its host/parent. */
public interface HostInterface {
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
index c5a3ea3ed..325af238a 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItem.java
@@ -162,61 +162,77 @@ public abstract class SpeedDialUiItem {
}
/**
- * Returns a video channel if there is exactly one video channel or the default channel is a video
- * channel.
+ * Returns one of the following:
+ *
+ * <ul>
+ * <li>The default channel if it's a video channel.
+ * <li>A video channel if it has the same attributes as the default channel, OR
+ * <li>null. (This is a deliberate product decision, even if there is only a single video
+ * reachable channel, we should still return null if it has different attributes from those
+ * in the default channel).
+ * </ul>
*/
@Nullable
- public Channel getDeterministicVideoChannel() {
- if (defaultChannel() != null && defaultChannel().isVideoTechnology()) {
+ public Channel getDefaultVideoChannel() {
+ if (defaultChannel() == null) {
+ return null;
+ }
+
+ if (defaultChannel().isVideoTechnology()) {
return defaultChannel();
}
- Channel videoChannel = null;
- for (Channel channel : channels()) {
- if (channel.isVideoTechnology()) {
- if (videoChannel != null) {
- // We found two video channels, so we can't determine which one is correct..
- return null;
- }
- videoChannel = channel;
- }
+ if (channels().size() == 1) {
+ // If there is only a single channel, it can't be a video channel
+ return null;
}
- // Only found one channel, so return it
- return videoChannel;
- }
- /** Returns true if any channels are video channels. */
- public boolean hasVideoChannels() {
- for (Channel channel : channels()) {
- if (channel.isVideoTechnology()) {
- return true;
+ // At this point, the default channel is a *voice* channel and there are more than
+ // one channel in total.
+ //
+ // Our defined assumptions about the channel list include that if a video channel
+ // follows a voice channel, it has the same attributes as that voice channel
+ // (see comments on method channels() for details).
+ //
+ // Therefore, if the default video channel exists, it must be the immediate successor
+ // of the default channel in the list.
+ //
+ // Note that we don't have to check if the last channel in the list is the default
+ // channel because even if it is, there will be no video channel under the assumption
+ // above.
+ for (int i = 0; i < channels().size() - 1; i++) {
+ // Find the default channel
+ if (Objects.equals(defaultChannel(), channels().get(i))) {
+ // Our defined assumptions about the list of channels is that if a video channel follows a
+ // voice channel, it has the same attributes as that voice channel.
+ Channel channel = channels().get(i + 1);
+ if (channel.isVideoTechnology()) {
+ return channel;
+ }
+ // Since the default voice channel isn't video reachable, we can't video call this number
+ return null;
}
}
- return false;
+ throw Assert.createIllegalStateFailException("channels() doesn't contain defaultChannel().");
}
/**
- * Returns a voice channel if there is exactly one voice channel or the default channel is a voice
+ * Returns a voice channel if there is exactly one channel or the default channel is a voice
* channel.
*/
@Nullable
- public Channel getDeterministicVoiceChannel() {
+ public Channel getDefaultVoiceChannel() {
if (defaultChannel() != null && !defaultChannel().isVideoTechnology()) {
return defaultChannel();
}
- Channel voiceChannel = null;
- for (Channel channel : channels()) {
- if (!channel.isVideoTechnology()) {
- if (voiceChannel != null) {
- // We found two voice channels, so we can't determine which one is correct..
- return null;
- }
- voiceChannel = channel;
- }
+ if (channels().size() == 1) {
+ // If there is only a single channel, it must be a voice channel as per our defined
+ // assumptions (detailed in comments on method channels()).
+ return channels().get(0);
}
- // Only found one channel, so return it
- return voiceChannel;
+
+ return null;
}
/**
@@ -254,6 +270,21 @@ public abstract class SpeedDialUiItem {
* enumerate each one here so that the user can choose the correct one. Each channel here
* represents a row in the {@link com.android.dialer.speeddial.DisambigDialog}.
*
+ * <p>These channels have a few very strictly enforced assumption that are used heavily throughout
+ * the codebase. Those assumption are that:
+ *
+ * <ol>
+ * <li>Each of the contact's numbers are voice reachable. So if a channel has it's technology
+ * set to anything other than {@link Channel#VOICE}, there is gaurenteed to be another
+ * channel with the exact same attributes, but technology will be {@link Channel#VOICE}.
+ * <li>For each of the contact's phone numbers, there will be a voice channel, then the next
+ * channel will either be the same phone number but a video channel, or a new number.
+ * </ol>
+ *
+ * For example: Say a contact has two phone numbers (A & B) and A is duo reachable. Then you can
+ * assume the list of channels will be ordered as either {A_voice, A_duo, B_voice} or {B_voice,
+ * A_voice, A_duo}.
+ *
* @see com.android.dialer.speeddial.database.SpeedDialEntry.Channel
*/
public abstract ImmutableList<Channel> channels();
diff --git a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
index 5dae2efab..e8892c431 100644
--- a/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
+++ b/java/com/android/dialer/speeddial/loader/SpeedDialUiItemMutator.java
@@ -54,6 +54,7 @@ import com.google.common.util.concurrent.ListeningExecutorService;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import javax.inject.Inject;
import javax.inject.Singleton;
@@ -109,6 +110,85 @@ public final class SpeedDialUiItemMutator {
}
/**
+ * Delete the SpeedDialUiItem.
+ *
+ * <p>If the item is starred, it's entry will be removed from the SpeedDialEntry database.
+ * Additionally, if the contact only has one entry in the database, it will be unstarred.
+ *
+ * <p>If the item isn't starred, it's usage data will be deleted but the suggestion can come back
+ * if the user calls that contact again.
+ *
+ * @return the updated list of SpeedDialUiItems.
+ */
+ public ListenableFuture<ImmutableList<SpeedDialUiItem>> removeSpeedDialUiItem(
+ SpeedDialUiItem speedDialUiItem) {
+ return dialerFutureSerializer.submit(
+ () -> removeSpeedDialUiItemInternal(speedDialUiItem), backgroundExecutor);
+ }
+
+ @WorkerThread
+ private ImmutableList<SpeedDialUiItem> removeSpeedDialUiItemInternal(
+ SpeedDialUiItem speedDialUiItem) {
+ Assert.isWorkerThread();
+ if (speedDialUiItem.isStarred()) {
+ removeStarredSpeedDialUiItem(speedDialUiItem);
+ } else {
+ removeSuggestedSpeedDialUiItem(speedDialUiItem);
+ }
+ return loadSpeedDialUiItemsInternal();
+ }
+
+ /**
+ * Delete the SpeedDialEntry associated with the passed in SpeedDialUiItem. Additionally, if the
+ * entry being deleted is the only entry for that contact, unstar it in the cp2.
+ */
+ @WorkerThread
+ private void removeStarredSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) {
+ Assert.isWorkerThread();
+ Assert.checkArgument(speedDialUiItem.isStarred());
+ SpeedDialEntryDao db = getSpeedDialEntryDao();
+ ImmutableList<SpeedDialEntry> entries = db.getAllEntries();
+
+ SpeedDialEntry entryToDelete = null;
+ int entriesForTheSameContact = 0;
+ for (SpeedDialEntry entry : entries) {
+ if (entry.contactId() == speedDialUiItem.contactId()) {
+ entriesForTheSameContact++;
+ }
+
+ if (Objects.equals(entry.id(), speedDialUiItem.speedDialEntryId())) {
+ Assert.checkArgument(entryToDelete == null);
+ entryToDelete = entry;
+ }
+ }
+ db.delete(ImmutableList.of(entryToDelete.id()));
+ if (entriesForTheSameContact == 1) {
+ unstarContact(speedDialUiItem);
+ }
+ }
+
+ @WorkerThread
+ private void unstarContact(SpeedDialUiItem speedDialUiItem) {
+ Assert.isWorkerThread();
+ ContentValues contentValues = new ContentValues();
+ contentValues.put(Phone.STARRED, 0);
+ appContext
+ .getContentResolver()
+ .update(
+ Phone.CONTENT_URI,
+ contentValues,
+ Phone.CONTACT_ID + " = ?",
+ new String[] {Long.toString(speedDialUiItem.contactId())});
+ }
+
+ @WorkerThread
+ @SuppressWarnings("unused")
+ private void removeSuggestedSpeedDialUiItem(SpeedDialUiItem speedDialUiItem) {
+ Assert.isWorkerThread();
+ // TODO(calderwoodra): remove strequent contact
+ }
+
+ /**
* Takes a contact uri from {@link Phone#CONTENT_URI} and updates {@link Phone#STARRED} to be
* true, if it isn't already or Inserts the contact into the {@link SpeedDialEntryDatabaseHelper}
*/