Search in sources :

Example 1 with SpeedDialEntry

use of com.android.dialer.speeddial.database.SpeedDialEntry in project android_packages_apps_Dialer by LineageOS.

the class DisambigDialog method updateDatabaseEntry.

@WorkerThread
private static void updateDatabaseEntry(Context appContext, SpeedDialUiItem item, Channel channel) {
    Assert.isWorkerThread();
    SpeedDialEntry entry = SpeedDialEntry.builder().setId(item.speedDialEntryId()).setContactId(item.contactId()).setLookupKey(item.lookupKey()).setDefaultChannel(channel).build();
    new SpeedDialEntryDatabaseHelper(appContext).update(ImmutableList.of(entry));
}
Also used : SpeedDialEntryDatabaseHelper(com.android.dialer.speeddial.database.SpeedDialEntryDatabaseHelper) SpeedDialEntry(com.android.dialer.speeddial.database.SpeedDialEntry) WorkerThread(android.support.annotation.WorkerThread)

Example 2 with SpeedDialEntry

use of com.android.dialer.speeddial.database.SpeedDialEntry in project android_packages_apps_Dialer by LineageOS.

the class SpeedDialUiItemMutator method updatePinnedPosition.

/**
 * Persists the position of the {@link SpeedDialUiItem items} as the pinned position according to
 * the order they were passed in.
 */
@WorkerThread
public void updatePinnedPosition(List<SpeedDialUiItem> speedDialUiItems) {
    Assert.isWorkerThread();
    if (speedDialUiItems == null || speedDialUiItems.isEmpty()) {
        return;
    }
    // Update the positions in the SpeedDialEntry database
    ImmutableList.Builder<SpeedDialEntry> entriesToUpdate = ImmutableList.builder();
    for (int i = 0; i < speedDialUiItems.size(); i++) {
        SpeedDialUiItem item = speedDialUiItems.get(i);
        if (item.isStarred()) {
            entriesToUpdate.add(item.buildSpeedDialEntry().toBuilder().setPinnedPosition(Optional.of(i)).build());
        }
    }
    getSpeedDialEntryDao().update(entriesToUpdate.build());
    // Update the positions in CP2
    // Build a list of SpeedDialUiItems where each contact is only represented once but the order
    // is maintained. For example, assume you have a list of contacts with contact ids:
    // > { 1, 1, 2, 1, 2, 3 }
    // This list will be reduced to:
    // > { 1, 2, 3 }
    // and their positions in the resulting list will be written to the CP2 Contacts.PINNED column.
    List<SpeedDialUiItem> cp2SpeedDialUiItems = new ArrayList<>();
    Set<Long> contactIds = new ArraySet<>();
    for (SpeedDialUiItem item : speedDialUiItems) {
        if (contactIds.add(item.contactId())) {
            cp2SpeedDialUiItems.add(item);
        }
    }
    // Code copied from PhoneFavoritesTileAdapter#handleDrop
    ArrayList<ContentProviderOperation> operations = new ArrayList<>();
    for (int i = 0; i < cp2SpeedDialUiItems.size(); i++) {
        SpeedDialUiItem item = cp2SpeedDialUiItems.get(i);
        // Pinned positions in the database start from 1 instead of being zero-indexed like
        // arrays, so offset by 1.
        int databasePinnedPosition = i + 1;
        if (item.pinnedPosition().isPresent() && item.pinnedPosition().get() == databasePinnedPosition) {
            continue;
        }
        Uri uri = Uri.withAppendedPath(Contacts.CONTENT_URI, String.valueOf(item.contactId()));
        ContentValues values = new ContentValues();
        values.put(Contacts.PINNED, databasePinnedPosition);
        operations.add(ContentProviderOperation.newUpdate(uri).withValues(values).build());
    }
    if (operations.isEmpty()) {
        // Nothing to update
        return;
    }
    try {
        appContext.getContentResolver().applyBatch(ContactsContract.AUTHORITY, operations);
    // TODO(calderwoodra): log
    } catch (RemoteException | OperationApplicationException e) {
        LogUtil.e("SpeedDialUiItemMutator.updatePinnedPosition", "Exception thrown when pinning contacts", e);
    }
}
Also used : ContentValues(android.content.ContentValues) ContentProviderOperation(android.content.ContentProviderOperation) ArraySet(android.util.ArraySet) ImmutableList(com.google.common.collect.ImmutableList) ArrayList(java.util.ArrayList) Uri(android.net.Uri) SpeedDialEntry(com.android.dialer.speeddial.database.SpeedDialEntry) RemoteException(android.os.RemoteException) OperationApplicationException(android.content.OperationApplicationException) WorkerThread(android.support.annotation.WorkerThread)

Example 3 with SpeedDialEntry

use of com.android.dialer.speeddial.database.SpeedDialEntry in project android_packages_apps_Dialer by LineageOS.

the class SpeedDialUiItemMutator method updateContactIdsAndLookupKeys.

/**
 * Returns the same list of SpeedDialEntries that are passed in except their contact ids and
 * lookup keys are updated to current values.
 *
 * <p>Unfortunately, we need to look up each contact individually to update the contact id and
 * lookup key. Luckily though, this query is highly optimized on the framework side and very
 * quick.
 */
@WorkerThread
private List<SpeedDialEntry> updateContactIdsAndLookupKeys(List<SpeedDialEntry> entries) {
    Assert.isWorkerThread();
    List<SpeedDialEntry> updatedEntries = new ArrayList<>();
    for (SpeedDialEntry entry : entries) {
        try (Cursor cursor = appContext.getContentResolver().query(Contacts.getLookupUri(entry.contactId(), entry.lookupKey()), new String[] { Contacts._ID, Contacts.LOOKUP_KEY }, null, null, null)) {
            if (cursor == null) {
                LogUtil.e("SpeedDialUiItemMutator.updateContactIdsAndLookupKeys", "null cursor");
                return new ArrayList<>();
            }
            if (cursor.getCount() == 0) {
                // No need to update this entry, the contact was deleted. We'll clear it up later.
                updatedEntries.add(entry);
                continue;
            }
            // Since all cursor rows will be have the same contact id and lookup key, just grab the
            // first one.
            cursor.moveToFirst();
            updatedEntries.add(entry.toBuilder().setContactId(cursor.getLong(0)).setLookupKey(cursor.getString(1)).build());
        }
    }
    return updatedEntries;
}
Also used : SpeedDialEntry(com.android.dialer.speeddial.database.SpeedDialEntry) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) WorkerThread(android.support.annotation.WorkerThread)

Example 4 with SpeedDialEntry

use of com.android.dialer.speeddial.database.SpeedDialEntry in project android_packages_apps_Dialer by LineageOS.

the class SpeedDialUiItemMutator method getSpeedDialUiItemsFromEntries.

/**
 * Returns a map of SpeedDialEntries to their corresponding SpeedDialUiItems. Mappings to null
 * elements imply that the contact was deleted.
 */
@WorkerThread
private Map<SpeedDialEntry, SpeedDialUiItem> getSpeedDialUiItemsFromEntries(List<SpeedDialEntry> entries) {
    Trace.beginSection("getSpeedDialUiItemsFromEntries");
    Assert.isWorkerThread();
    // Fetch the contact ids from the SpeedDialEntries
    Set<String> contactIds = new ArraySet<>();
    entries.forEach(entry -> contactIds.add(Long.toString(entry.contactId())));
    if (contactIds.isEmpty()) {
        Trace.endSection();
        return new ArrayMap<>();
    }
    // Build SpeedDialUiItems from those contact ids and map them to their entries
    Selection selection = Selection.builder().and(Selection.column(Phone.CONTACT_ID).in(contactIds)).build();
    try (Cursor cursor = appContext.getContentResolver().query(Phone.CONTENT_URI, SpeedDialUiItem.getPhoneProjection(isPrimaryDisplayNameOrder()), selection.getSelection(), selection.getSelectionArgs(), null)) {
        Map<SpeedDialEntry, SpeedDialUiItem> map = new ArrayMap<>();
        for (cursor.moveToFirst(); !cursor.isAfterLast(); ) /* Iterate in the loop */
        {
            SpeedDialUiItem item = SpeedDialUiItem.fromCursor(appContext.getResources(), cursor, CallUtil.isVideoEnabled(appContext));
            for (SpeedDialEntry entry : entries) {
                if (entry.contactId() == item.contactId()) {
                    // Update the id and pinned position to match it's corresponding SpeedDialEntry.
                    SpeedDialUiItem.Builder entrySpeedDialItem = item.toBuilder().setSpeedDialEntryId(entry.id()).setPinnedPosition(entry.pinnedPosition());
                    // Preserve the default channel if it didn't change/still exists
                    Channel defaultChannel = entry.defaultChannel();
                    if (defaultChannel != null) {
                        if (item.channels().contains(defaultChannel) || isValidDuoDefaultChannel(item.channels(), defaultChannel)) {
                            entrySpeedDialItem.setDefaultChannel(defaultChannel);
                        }
                    }
                    // It's impossible for two contacts to exist with the same contact id, so if this entry
                    // was previously matched to a SpeedDialUiItem and is being matched again, something
                    // went horribly wrong.
                    Assert.checkArgument(map.put(entry, entrySpeedDialItem.build()) == null, "Each SpeedDialEntry only has one correct SpeedDialUiItem");
                }
            }
        }
        // Contact must have been deleted
        for (SpeedDialEntry entry : entries) {
            map.putIfAbsent(entry, null);
        }
        Trace.endSection();
        return map;
    }
}
Also used : ArraySet(android.util.ArraySet) Selection(com.android.dialer.common.database.Selection) SpeedDialEntry(com.android.dialer.speeddial.database.SpeedDialEntry) Channel(com.android.dialer.speeddial.database.SpeedDialEntry.Channel) ArrayMap(android.util.ArrayMap) Cursor(android.database.Cursor) WorkerThread(android.support.annotation.WorkerThread)

Example 5 with SpeedDialEntry

use of com.android.dialer.speeddial.database.SpeedDialEntry in project android_packages_apps_Dialer by LineageOS.

the class SpeedDialUiItemMutator method removeStarredSpeedDialUiItem.

/**
 * 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);
    }
}
Also used : SpeedDialEntryDao(com.android.dialer.speeddial.database.SpeedDialEntryDao) SpeedDialEntry(com.android.dialer.speeddial.database.SpeedDialEntry) WorkerThread(android.support.annotation.WorkerThread)

Aggregations

SpeedDialEntry (com.android.dialer.speeddial.database.SpeedDialEntry)8 WorkerThread (android.support.annotation.WorkerThread)7 ArrayList (java.util.ArrayList)3 Cursor (android.database.Cursor)2 Uri (android.net.Uri)2 ArraySet (android.util.ArraySet)2 SpeedDialEntryDao (com.android.dialer.speeddial.database.SpeedDialEntryDao)2 ImmutableList (com.google.common.collect.ImmutableList)2 ContentProviderOperation (android.content.ContentProviderOperation)1 ContentValues (android.content.ContentValues)1 OperationApplicationException (android.content.OperationApplicationException)1 RemoteException (android.os.RemoteException)1 ArrayMap (android.util.ArrayMap)1 Selection (com.android.dialer.common.database.Selection)1 Channel (com.android.dialer.speeddial.database.SpeedDialEntry.Channel)1 SpeedDialEntryDatabaseHelper (com.android.dialer.speeddial.database.SpeedDialEntryDatabaseHelper)1