1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License 15 */ 16 17 package com.android.dialer.calllog.ui.menu; 18 19 import android.Manifest.permission; 20 import android.content.Context; 21 import android.provider.CallLog; 22 import android.provider.CallLog.Calls; 23 import android.support.annotation.Nullable; 24 import android.support.annotation.RequiresPermission; 25 import com.android.dialer.CoalescedIds; 26 import com.android.dialer.common.Assert; 27 import com.android.dialer.common.LogUtil; 28 import com.android.dialer.common.concurrent.DialerExecutor.Worker; 29 import com.android.dialer.common.concurrent.DialerExecutorComponent; 30 import com.android.dialer.common.database.Selection; 31 import com.android.dialer.historyitemactions.HistoryItemActionModule; 32 import com.android.dialer.logging.DialerImpression; 33 import com.android.dialer.logging.Logger; 34 import java.lang.ref.WeakReference; 35 import java.util.ArrayList; 36 import java.util.List; 37 38 /** {@link HistoryItemActionModule} for deleting a call log item in the new call log. */ 39 final class DeleteCallLogItemModule implements HistoryItemActionModule { 40 private static final String TAG = DeleteCallLogItemModule.class.getName(); 41 42 private final Context context; 43 private final CoalescedIds coalescedIds; 44 DeleteCallLogItemModule(Context context, CoalescedIds coalescedIds)45 DeleteCallLogItemModule(Context context, CoalescedIds coalescedIds) { 46 this.context = context; 47 this.coalescedIds = coalescedIds; 48 } 49 50 @Override getStringId()51 public int getStringId() { 52 return R.string.delete; 53 } 54 55 @Override getDrawableId()56 public int getDrawableId() { 57 return R.drawable.quantum_ic_delete_vd_theme_24; 58 } 59 60 @Override onClick()61 public boolean onClick() { 62 DialerExecutorComponent.get(context) 63 .dialerExecutorFactory() 64 .createNonUiTaskBuilder(new CallLogItemDeletionWorker(context)) 65 .build() 66 .executeSerial(coalescedIds); 67 68 Logger.get(context).logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM); 69 return true; 70 } 71 72 /** 73 * A {@link Worker} that deletes a call log item. 74 * 75 * <p>It takes as input the IDs of all call log records that are coalesced into the item to be 76 * deleted. 77 */ 78 private static class CallLogItemDeletionWorker implements Worker<CoalescedIds, Void> { 79 private final WeakReference<Context> contextWeakReference; 80 CallLogItemDeletionWorker(Context context)81 CallLogItemDeletionWorker(Context context) { 82 contextWeakReference = new WeakReference<>(context); 83 } 84 85 @Nullable 86 @Override 87 @RequiresPermission(value = permission.WRITE_CALL_LOG) doInBackground(CoalescedIds coalescedIds)88 public Void doInBackground(CoalescedIds coalescedIds) throws Throwable { 89 Context context = contextWeakReference.get(); 90 if (context == null) { 91 LogUtil.e(TAG, "Unable to delete an call log item due to null context."); 92 return null; 93 } 94 95 Selection selection = 96 Selection.builder() 97 .and(Selection.column(CallLog.Calls._ID).in(getCallLogIdsAsStrings(coalescedIds))) 98 .build(); 99 int numRowsDeleted = 100 context 101 .getContentResolver() 102 .delete(Calls.CONTENT_URI, selection.getSelection(), selection.getSelectionArgs()); 103 104 if (numRowsDeleted != coalescedIds.getCoalescedIdCount()) { 105 LogUtil.e( 106 TAG, 107 "Deleting call log item is unsuccessful. %d of %d rows are deleted.", 108 numRowsDeleted, 109 coalescedIds.getCoalescedIdCount()); 110 } 111 112 return null; 113 } 114 getCallLogIdsAsStrings(CoalescedIds coalescedIds)115 private static List<String> getCallLogIdsAsStrings(CoalescedIds coalescedIds) { 116 Assert.checkArgument(coalescedIds.getCoalescedIdCount() > 0); 117 118 List<String> idStrings = new ArrayList<>(coalescedIds.getCoalescedIdCount()); 119 120 for (long callLogId : coalescedIds.getCoalescedIdList()) { 121 idStrings.add(String.valueOf(callLogId)); 122 } 123 124 return idStrings; 125 } 126 } 127 } 128