Loading assets/quantum/res/drawable/quantum_ic_exit_to_app_vd_theme_24.xml 0 → 100644 +25 −0 Original line number Original line 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 --> <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="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/> </vector> No newline at end of file java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +70 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.dialer.app.calllog; package com.android.dialer.app.calllog; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Context; Loading @@ -28,6 +30,7 @@ import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.annotation.IntDef; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.CardView; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; Loading Loading @@ -68,6 +71,7 @@ import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; import com.android.dialer.clipboard.ClipboardUtils; import com.android.dialer.clipboard.ClipboardUtils; import com.android.dialer.common.Assert; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutors; import com.android.dialer.compat.CompatUtils; import com.android.dialer.compat.CompatUtils; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.constants.ActivityRequestCodes; Loading Loading @@ -95,6 +99,7 @@ import com.android.dialer.util.DialerUtils; import com.android.dialer.util.UriUtils; import com.android.dialer.util.UriUtils; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; /** /** * This is an object containing references to views contained by the call log list item. This * This is an object containing references to views contained by the call log list item. This Loading @@ -107,6 +112,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, implements View.OnClickListener, MenuItem.OnMenuItemClickListener, MenuItem.OnMenuItemClickListener, View.OnCreateContextMenuListener { View.OnCreateContextMenuListener { private static final String TASK_DELETE = "task_delete"; /** The root view of the call log list item */ /** The root view of the call log list item */ public final View rootView; public final View rootView; /** The quick contact badge for the contact. */ /** The quick contact badge for the contact. */ Loading Loading @@ -431,6 +439,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder .logImpression(DialerImpression.Type.CALL_LOG_CONTEXT_MENU_REPORT_AS_NOT_SPAM); .logImpression(DialerImpression.Type.CALL_LOG_CONTEXT_MENU_REPORT_AS_NOT_SPAM); mBlockReportListener.onReportNotSpam( mBlockReportListener.onReportNotSpam( displayNumber, number, countryIso, callType, info.sourceType); displayNumber, number, countryIso, callType, info.sourceType); } else if (resId == R.id.context_menu_delete) { AsyncTaskExecutors.createAsyncTaskExecutor() .submit(TASK_DELETE, new DeleteCallTask(mContext, callIds)); } } return false; return false; } } Loading Loading @@ -1217,6 +1228,11 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } } } } if (callType != CallLog.Calls.VOICEMAIL_TYPE) { menu.add(ContextMenu.NONE, R.id.context_menu_delete, ContextMenu.NONE, R.string.delete) .setOnMenuItemClickListener(this); } Logger.get(mContext).logScreenView(ScreenEvent.Type.CALL_LOG_CONTEXT_MENU, (Activity) mContext); Logger.get(mContext).logScreenView(ScreenEvent.Type.CALL_LOG_CONTEXT_MENU, (Activity) mContext); } } Loading Loading @@ -1261,4 +1277,58 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder int callType, int callType, ContactSource.Type contactSourceType); ContactSource.Type contactSourceType); } } private static class DeleteCallTask extends AsyncTask<Void, Void, Void> { // Using a weak reference to hold the Context so that there is no memory leak. private final WeakReference<Context> contextWeakReference; private final String callIdsStr; DeleteCallTask(Context context, long[] callIdsArray) { this.contextWeakReference = new WeakReference<>(context); this.callIdsStr = concatCallIds(callIdsArray); } @Override // Suppress the lint check here as the user will not be able to see call log entries if // permission.WRITE_CALL_LOG is not granted. @SuppressLint("MissingPermission") @RequiresPermission(value = permission.WRITE_CALL_LOG) protected Void doInBackground(Void... params) { Context context = contextWeakReference.get(); if (context == null) { return null; } if (callIdsStr != null) { context .getContentResolver() .delete( Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIdsStr + ")" /* where */, null /* selectionArgs */); } return null; } @Override public void onPostExecute(Void result) {} private String concatCallIds(long[] callIds) { if (callIds == null || callIds.length == 0) { return null; } StringBuilder str = new StringBuilder(); for (long callId : callIds) { if (str.length() != 0) { str.append(","); } str.append(callId); } return str.toString(); } } } } java/com/android/dialer/app/res/values/ids.xml +2 −1 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,7 @@ --> --> <resources> <resources> <item name="call_detail_delete_menu_item" type="id"/> <item name="call_detail_action_delete" type="id"/> <item name="context_menu_copy_to_clipboard" type="id"/> <item name="context_menu_copy_to_clipboard" type="id"/> <item name="context_menu_copy_transcript_to_clipboard" type="id"/> <item name="context_menu_copy_transcript_to_clipboard" type="id"/> <item name="context_menu_edit_before_call" type="id"/> <item name="context_menu_edit_before_call" type="id"/> Loading @@ -23,6 +23,7 @@ <item name="context_menu_block" type="id"/> <item name="context_menu_block" type="id"/> <item name="context_menu_unblock" type="id"/> <item name="context_menu_unblock" type="id"/> <item name="context_menu_report_not_spam" type="id"/> <item name="context_menu_report_not_spam" type="id"/> <item name="context_menu_delete" type="id"/> <item name="settings_header_sounds_and_vibration" type="id"/> <item name="settings_header_sounds_and_vibration" type="id"/> <item name="block_id" type="id"/> <item name="block_id" type="id"/> </resources> </resources> java/com/android/dialer/calldetails/CallDetailsActivity.java +52 −26 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.dialer.calldetails; package com.android.dialer.calldetails; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading @@ -25,14 +28,14 @@ import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.CallLog.Calls; import android.support.annotation.NonNull; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar.OnMenuItemClickListener; import android.view.MenuItem; import android.widget.Toast; import android.widget.Toast; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsFooterViewHolder.DeleteCallDetailsListener; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.Assert; Loading @@ -52,15 +55,16 @@ import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; import com.android.dialer.protos.ProtoParsers; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; /** Displays the details of a specific call log entry. */ /** Displays the details of a specific call log entry. */ public class CallDetailsActivity extends AppCompatActivity public class CallDetailsActivity extends AppCompatActivity implements OnMenuItemClickListener, implements CallDetailsHeaderViewHolder.CallbackActionListener, CallDetailsHeaderViewHolder.CallbackActionListener, CallDetailsFooterViewHolder.ReportCallIdListener, CallDetailsFooterViewHolder.ReportCallIdListener, DeleteCallDetailsListener, HistoricalDataChangedListener { HistoricalDataChangedListener { public static final String EXTRA_PHONE_NUMBER = "phone_number"; public static final String EXTRA_PHONE_NUMBER = "phone_number"; Loading Loading @@ -102,8 +106,6 @@ public class CallDetailsActivity extends AppCompatActivity super.onCreate(savedInstanceState); super.onCreate(savedInstanceState); setContentView(R.layout.call_details_activity); setContentView(R.layout.call_details_activity); Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar); toolbar.inflateMenu(R.menu.call_details_menu); toolbar.setOnMenuItemClickListener(this); toolbar.setTitle(R.string.call_details); toolbar.setTitle(R.string.call_details); toolbar.setNavigationOnClickListener( toolbar.setNavigationOnClickListener( v -> { v -> { Loading Loading @@ -160,7 +162,8 @@ public class CallDetailsActivity extends AppCompatActivity contact, contact, entries.getEntriesList(), entries.getEntriesList(), this /* callbackListener */, this /* callbackListener */, this /* reportCallIdListener */); this /* reportCallIdListener */, this /* callDetailDeletionListener */); RecyclerView recyclerView = findViewById(R.id.recycler_view); RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setLayoutManager(new LinearLayoutManager(this)); Loading @@ -168,17 +171,6 @@ public class CallDetailsActivity extends AppCompatActivity PerformanceReport.logOnScrollStateChange(recyclerView); PerformanceReport.logOnScrollStateChange(recyclerView); } } @Override public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == R.id.call_detail_delete_menu_item) { Logger.get(this).logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM); AsyncTaskExecutors.createAsyncTaskExecutor().submit(TASK_DELETE, new DeleteCallsTask()); item.setEnabled(false); return true; } return false; } @Override @Override public void onBackPressed() { public void onBackPressed() { PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); Loading Loading @@ -246,6 +238,12 @@ public class CallDetailsActivity extends AppCompatActivity PreCall.start(this, callIntentBuilder); PreCall.start(this, callIntentBuilder); } } @Override public void delete() { AsyncTaskExecutors.createAsyncTaskExecutor() .submit(TASK_DELETE, new DeleteCallsTask(this, contact, entries)); } @NonNull @NonNull private Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( private Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( @Nullable String number, @NonNull CallDetailsEntries entries) { @Nullable String number, @NonNull CallDetailsEntries entries) { Loading Loading @@ -287,13 +285,22 @@ public class CallDetailsActivity extends AppCompatActivity } } /** Delete specified calls from the call log. */ /** Delete specified calls from the call log. */ private class DeleteCallsTask extends AsyncTask<Void, Void, Void> { private static class DeleteCallsTask extends AsyncTask<Void, Void, Void> { // Use a weak reference to hold the Activity so that there is no memory leak. private final WeakReference<Activity> activityWeakReference; private final DialerContact contact; private final CallDetailsEntries callDetailsEntries; private final String callIds; private final String callIds; DeleteCallsTask() { DeleteCallsTask( Activity activity, DialerContact contact, CallDetailsEntries callDetailsEntries) { this.activityWeakReference = new WeakReference<>(activity); this.contact = contact; this.callDetailsEntries = callDetailsEntries; StringBuilder callIds = new StringBuilder(); StringBuilder callIds = new StringBuilder(); for (CallDetailsEntry entry : entries.getEntriesList()) { for (CallDetailsEntry entry : callDetailsEntries.getEntriesList()) { if (callIds.length() != 0) { if (callIds.length() != 0) { callIds.append(","); callIds.append(","); } } Loading @@ -303,24 +310,43 @@ public class CallDetailsActivity extends AppCompatActivity } } @Override @Override // Suppress the lint check here as the user will not be able to see call log entries if // permission.WRITE_CALL_LOG is not granted. @SuppressLint("MissingPermission") @RequiresPermission(value = permission.WRITE_CALL_LOG) protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) { getContentResolver() Activity activity = activityWeakReference.get(); .delete(Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIds + ")", null); if (activity == null) { return null; } activity .getContentResolver() .delete( Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIds + ")" /* where */, null /* selectionArgs */); return null; return null; } } @Override @Override public void onPostExecute(Void result) { public void onPostExecute(Void result) { Activity activity = activityWeakReference.get(); if (activity == null) { return; } Intent data = new Intent(); Intent data = new Intent(); data.putExtra(EXTRA_PHONE_NUMBER, contact.getNumber()); data.putExtra(EXTRA_PHONE_NUMBER, contact.getNumber()); for (CallDetailsEntry entry : entries.getEntriesList()) { for (CallDetailsEntry entry : callDetailsEntries.getEntriesList()) { if (entry.getHistoryResultsCount() > 0) { if (entry.getHistoryResultsCount() > 0) { data.putExtra(EXTRA_HAS_ENRICHED_CALL_DATA, true); data.putExtra(EXTRA_HAS_ENRICHED_CALL_DATA, true); break; break; } } } } setResult(RESULT_OK, data); finish(); activity.setResult(RESULT_OK, data); activity.finish(); } } } } } } java/com/android/dialer/calldetails/CallDetailsAdapter.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.ViewGroup; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsFooterViewHolder.DeleteCallDetailsListener; import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallbackActionListener; import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallbackActionListener; import com.android.dialer.calllogutils.CallTypeHelper; import com.android.dialer.calllogutils.CallTypeHelper; import com.android.dialer.calllogutils.CallbackActionHelper; import com.android.dialer.calllogutils.CallbackActionHelper; Loading @@ -42,6 +43,7 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol private final DialerContact contact; private final DialerContact contact; private final CallbackActionListener callbackActionListener; private final CallbackActionListener callbackActionListener; private final CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener; private final CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener; private final DeleteCallDetailsListener deleteCallDetailsListener; private final CallTypeHelper callTypeHelper; private final CallTypeHelper callTypeHelper; private List<CallDetailsEntry> callDetailsEntries; private List<CallDetailsEntry> callDetailsEntries; Loading @@ -50,11 +52,13 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol @NonNull DialerContact contact, @NonNull DialerContact contact, @NonNull List<CallDetailsEntry> callDetailsEntries, @NonNull List<CallDetailsEntry> callDetailsEntries, CallbackActionListener callbackActionListener, CallbackActionListener callbackActionListener, CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener) { CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener, DeleteCallDetailsListener deleteCallDetailsListener) { this.contact = Assert.isNotNull(contact); this.contact = Assert.isNotNull(contact); this.callDetailsEntries = callDetailsEntries; this.callDetailsEntries = callDetailsEntries; this.callbackActionListener = callbackActionListener; this.callbackActionListener = callbackActionListener; this.reportCallIdListener = reportCallIdListener; this.reportCallIdListener = reportCallIdListener; this.deleteCallDetailsListener = deleteCallDetailsListener; callTypeHelper = new CallTypeHelper(context.getResources(), DuoComponent.get(context).getDuo()); callTypeHelper = new CallTypeHelper(context.getResources(), DuoComponent.get(context).getDuo()); } } Loading @@ -70,7 +74,9 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol inflater.inflate(R.layout.call_details_entry, parent, false)); inflater.inflate(R.layout.call_details_entry, parent, false)); case FOOTER_VIEW_TYPE: case FOOTER_VIEW_TYPE: return new CallDetailsFooterViewHolder( return new CallDetailsFooterViewHolder( inflater.inflate(R.layout.call_details_footer, parent, false), reportCallIdListener); inflater.inflate(R.layout.call_details_footer, parent, false), reportCallIdListener, deleteCallDetailsListener); default: default: throw Assert.createIllegalStateFailException( throw Assert.createIllegalStateFailException( "No ViewHolder available for viewType: " + viewType); "No ViewHolder available for viewType: " + viewType); Loading Loading
assets/quantum/res/drawable/quantum_ic_exit_to_app_vd_theme_24.xml 0 → 100644 +25 −0 Original line number Original line 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 --> <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="M10.09,15.59L11.5,17l5,-5 -5,-5 -1.41,1.41L12.67,11H3v2h9.67l-2.58,2.59zM19,3H5c-1.11,0 -2,0.9 -2,2v4h2V5h14v14H5v-4H3v4c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2V5c0,-1.1 -0.9,-2 -2,-2z"/> </vector> No newline at end of file
java/com/android/dialer/app/calllog/CallLogListItemViewHolder.java +70 −0 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.dialer.app.calllog; package com.android.dialer.app.calllog; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Context; Loading @@ -28,6 +30,7 @@ import android.provider.CallLog.Calls; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.provider.ContactsContract.CommonDataKinds.Phone; import android.support.annotation.IntDef; import android.support.annotation.IntDef; import android.support.annotation.Nullable; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; import android.support.annotation.VisibleForTesting; import android.support.annotation.VisibleForTesting; import android.support.v7.widget.CardView; import android.support.v7.widget.CardView; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; Loading Loading @@ -68,6 +71,7 @@ import com.android.dialer.calllogutils.CallbackActionHelper.CallbackAction; import com.android.dialer.clipboard.ClipboardUtils; import com.android.dialer.clipboard.ClipboardUtils; import com.android.dialer.common.Assert; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutors; import com.android.dialer.compat.CompatUtils; import com.android.dialer.compat.CompatUtils; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.configprovider.ConfigProviderBindings; import com.android.dialer.constants.ActivityRequestCodes; import com.android.dialer.constants.ActivityRequestCodes; Loading Loading @@ -95,6 +99,7 @@ import com.android.dialer.util.DialerUtils; import com.android.dialer.util.UriUtils; import com.android.dialer.util.UriUtils; import java.lang.annotation.Retention; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy; import java.lang.ref.WeakReference; /** /** * This is an object containing references to views contained by the call log list item. This * This is an object containing references to views contained by the call log list item. This Loading @@ -107,6 +112,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener, implements View.OnClickListener, MenuItem.OnMenuItemClickListener, MenuItem.OnMenuItemClickListener, View.OnCreateContextMenuListener { View.OnCreateContextMenuListener { private static final String TASK_DELETE = "task_delete"; /** The root view of the call log list item */ /** The root view of the call log list item */ public final View rootView; public final View rootView; /** The quick contact badge for the contact. */ /** The quick contact badge for the contact. */ Loading Loading @@ -431,6 +439,9 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder .logImpression(DialerImpression.Type.CALL_LOG_CONTEXT_MENU_REPORT_AS_NOT_SPAM); .logImpression(DialerImpression.Type.CALL_LOG_CONTEXT_MENU_REPORT_AS_NOT_SPAM); mBlockReportListener.onReportNotSpam( mBlockReportListener.onReportNotSpam( displayNumber, number, countryIso, callType, info.sourceType); displayNumber, number, countryIso, callType, info.sourceType); } else if (resId == R.id.context_menu_delete) { AsyncTaskExecutors.createAsyncTaskExecutor() .submit(TASK_DELETE, new DeleteCallTask(mContext, callIds)); } } return false; return false; } } Loading Loading @@ -1217,6 +1228,11 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder } } } } if (callType != CallLog.Calls.VOICEMAIL_TYPE) { menu.add(ContextMenu.NONE, R.id.context_menu_delete, ContextMenu.NONE, R.string.delete) .setOnMenuItemClickListener(this); } Logger.get(mContext).logScreenView(ScreenEvent.Type.CALL_LOG_CONTEXT_MENU, (Activity) mContext); Logger.get(mContext).logScreenView(ScreenEvent.Type.CALL_LOG_CONTEXT_MENU, (Activity) mContext); } } Loading Loading @@ -1261,4 +1277,58 @@ public final class CallLogListItemViewHolder extends RecyclerView.ViewHolder int callType, int callType, ContactSource.Type contactSourceType); ContactSource.Type contactSourceType); } } private static class DeleteCallTask extends AsyncTask<Void, Void, Void> { // Using a weak reference to hold the Context so that there is no memory leak. private final WeakReference<Context> contextWeakReference; private final String callIdsStr; DeleteCallTask(Context context, long[] callIdsArray) { this.contextWeakReference = new WeakReference<>(context); this.callIdsStr = concatCallIds(callIdsArray); } @Override // Suppress the lint check here as the user will not be able to see call log entries if // permission.WRITE_CALL_LOG is not granted. @SuppressLint("MissingPermission") @RequiresPermission(value = permission.WRITE_CALL_LOG) protected Void doInBackground(Void... params) { Context context = contextWeakReference.get(); if (context == null) { return null; } if (callIdsStr != null) { context .getContentResolver() .delete( Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIdsStr + ")" /* where */, null /* selectionArgs */); } return null; } @Override public void onPostExecute(Void result) {} private String concatCallIds(long[] callIds) { if (callIds == null || callIds.length == 0) { return null; } StringBuilder str = new StringBuilder(); for (long callId : callIds) { if (str.length() != 0) { str.append(","); } str.append(callId); } return str.toString(); } } } }
java/com/android/dialer/app/res/values/ids.xml +2 −1 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,7 @@ --> --> <resources> <resources> <item name="call_detail_delete_menu_item" type="id"/> <item name="call_detail_action_delete" type="id"/> <item name="context_menu_copy_to_clipboard" type="id"/> <item name="context_menu_copy_to_clipboard" type="id"/> <item name="context_menu_copy_transcript_to_clipboard" type="id"/> <item name="context_menu_copy_transcript_to_clipboard" type="id"/> <item name="context_menu_edit_before_call" type="id"/> <item name="context_menu_edit_before_call" type="id"/> Loading @@ -23,6 +23,7 @@ <item name="context_menu_block" type="id"/> <item name="context_menu_block" type="id"/> <item name="context_menu_unblock" type="id"/> <item name="context_menu_unblock" type="id"/> <item name="context_menu_report_not_spam" type="id"/> <item name="context_menu_report_not_spam" type="id"/> <item name="context_menu_delete" type="id"/> <item name="settings_header_sounds_and_vibration" type="id"/> <item name="settings_header_sounds_and_vibration" type="id"/> <item name="block_id" type="id"/> <item name="block_id" type="id"/> </resources> </resources>
java/com/android/dialer/calldetails/CallDetailsActivity.java +52 −26 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.dialer.calldetails; package com.android.dialer.calldetails; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; Loading @@ -25,14 +28,14 @@ import android.provider.CallLog; import android.provider.CallLog.Calls; import android.provider.CallLog.Calls; import android.support.annotation.NonNull; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.support.annotation.Nullable; import android.support.annotation.RequiresPermission; import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar; import android.support.v7.widget.Toolbar.OnMenuItemClickListener; import android.view.MenuItem; import android.widget.Toast; import android.widget.Toast; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsFooterViewHolder.DeleteCallDetailsListener; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.common.Assert; import com.android.dialer.common.Assert; Loading @@ -52,15 +55,16 @@ import com.android.dialer.performancereport.PerformanceReport; import com.android.dialer.postcall.PostCall; import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; import com.android.dialer.protos.ProtoParsers; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.Collections; import java.util.List; import java.util.List; import java.util.Map; import java.util.Map; /** Displays the details of a specific call log entry. */ /** Displays the details of a specific call log entry. */ public class CallDetailsActivity extends AppCompatActivity public class CallDetailsActivity extends AppCompatActivity implements OnMenuItemClickListener, implements CallDetailsHeaderViewHolder.CallbackActionListener, CallDetailsHeaderViewHolder.CallbackActionListener, CallDetailsFooterViewHolder.ReportCallIdListener, CallDetailsFooterViewHolder.ReportCallIdListener, DeleteCallDetailsListener, HistoricalDataChangedListener { HistoricalDataChangedListener { public static final String EXTRA_PHONE_NUMBER = "phone_number"; public static final String EXTRA_PHONE_NUMBER = "phone_number"; Loading Loading @@ -102,8 +106,6 @@ public class CallDetailsActivity extends AppCompatActivity super.onCreate(savedInstanceState); super.onCreate(savedInstanceState); setContentView(R.layout.call_details_activity); setContentView(R.layout.call_details_activity); Toolbar toolbar = findViewById(R.id.toolbar); Toolbar toolbar = findViewById(R.id.toolbar); toolbar.inflateMenu(R.menu.call_details_menu); toolbar.setOnMenuItemClickListener(this); toolbar.setTitle(R.string.call_details); toolbar.setTitle(R.string.call_details); toolbar.setNavigationOnClickListener( toolbar.setNavigationOnClickListener( v -> { v -> { Loading Loading @@ -160,7 +162,8 @@ public class CallDetailsActivity extends AppCompatActivity contact, contact, entries.getEntriesList(), entries.getEntriesList(), this /* callbackListener */, this /* callbackListener */, this /* reportCallIdListener */); this /* reportCallIdListener */, this /* callDetailDeletionListener */); RecyclerView recyclerView = findViewById(R.id.recycler_view); RecyclerView recyclerView = findViewById(R.id.recycler_view); recyclerView.setLayoutManager(new LinearLayoutManager(this)); recyclerView.setLayoutManager(new LinearLayoutManager(this)); Loading @@ -168,17 +171,6 @@ public class CallDetailsActivity extends AppCompatActivity PerformanceReport.logOnScrollStateChange(recyclerView); PerformanceReport.logOnScrollStateChange(recyclerView); } } @Override public boolean onMenuItemClick(MenuItem item) { if (item.getItemId() == R.id.call_detail_delete_menu_item) { Logger.get(this).logImpression(DialerImpression.Type.USER_DELETED_CALL_LOG_ITEM); AsyncTaskExecutors.createAsyncTaskExecutor().submit(TASK_DELETE, new DeleteCallsTask()); item.setEnabled(false); return true; } return false; } @Override @Override public void onBackPressed() { public void onBackPressed() { PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); PerformanceReport.recordClick(UiAction.Type.PRESS_ANDROID_BACK_BUTTON); Loading Loading @@ -246,6 +238,12 @@ public class CallDetailsActivity extends AppCompatActivity PreCall.start(this, callIntentBuilder); PreCall.start(this, callIntentBuilder); } } @Override public void delete() { AsyncTaskExecutors.createAsyncTaskExecutor() .submit(TASK_DELETE, new DeleteCallsTask(this, contact, entries)); } @NonNull @NonNull private Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( private Map<CallDetailsEntry, List<HistoryResult>> getAllHistoricalData( @Nullable String number, @NonNull CallDetailsEntries entries) { @Nullable String number, @NonNull CallDetailsEntries entries) { Loading Loading @@ -287,13 +285,22 @@ public class CallDetailsActivity extends AppCompatActivity } } /** Delete specified calls from the call log. */ /** Delete specified calls from the call log. */ private class DeleteCallsTask extends AsyncTask<Void, Void, Void> { private static class DeleteCallsTask extends AsyncTask<Void, Void, Void> { // Use a weak reference to hold the Activity so that there is no memory leak. private final WeakReference<Activity> activityWeakReference; private final DialerContact contact; private final CallDetailsEntries callDetailsEntries; private final String callIds; private final String callIds; DeleteCallsTask() { DeleteCallsTask( Activity activity, DialerContact contact, CallDetailsEntries callDetailsEntries) { this.activityWeakReference = new WeakReference<>(activity); this.contact = contact; this.callDetailsEntries = callDetailsEntries; StringBuilder callIds = new StringBuilder(); StringBuilder callIds = new StringBuilder(); for (CallDetailsEntry entry : entries.getEntriesList()) { for (CallDetailsEntry entry : callDetailsEntries.getEntriesList()) { if (callIds.length() != 0) { if (callIds.length() != 0) { callIds.append(","); callIds.append(","); } } Loading @@ -303,24 +310,43 @@ public class CallDetailsActivity extends AppCompatActivity } } @Override @Override // Suppress the lint check here as the user will not be able to see call log entries if // permission.WRITE_CALL_LOG is not granted. @SuppressLint("MissingPermission") @RequiresPermission(value = permission.WRITE_CALL_LOG) protected Void doInBackground(Void... params) { protected Void doInBackground(Void... params) { getContentResolver() Activity activity = activityWeakReference.get(); .delete(Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIds + ")", null); if (activity == null) { return null; } activity .getContentResolver() .delete( Calls.CONTENT_URI, CallLog.Calls._ID + " IN (" + callIds + ")" /* where */, null /* selectionArgs */); return null; return null; } } @Override @Override public void onPostExecute(Void result) { public void onPostExecute(Void result) { Activity activity = activityWeakReference.get(); if (activity == null) { return; } Intent data = new Intent(); Intent data = new Intent(); data.putExtra(EXTRA_PHONE_NUMBER, contact.getNumber()); data.putExtra(EXTRA_PHONE_NUMBER, contact.getNumber()); for (CallDetailsEntry entry : entries.getEntriesList()) { for (CallDetailsEntry entry : callDetailsEntries.getEntriesList()) { if (entry.getHistoryResultsCount() > 0) { if (entry.getHistoryResultsCount() > 0) { data.putExtra(EXTRA_HAS_ENRICHED_CALL_DATA, true); data.putExtra(EXTRA_HAS_ENRICHED_CALL_DATA, true); break; break; } } } } setResult(RESULT_OK, data); finish(); activity.setResult(RESULT_OK, data); activity.finish(); } } } } } }
java/com/android/dialer/calldetails/CallDetailsAdapter.java +8 −2 Original line number Original line Diff line number Diff line Loading @@ -23,6 +23,7 @@ import android.support.v7.widget.RecyclerView.ViewHolder; import android.view.LayoutInflater; import android.view.LayoutInflater; import android.view.ViewGroup; import android.view.ViewGroup; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calldetails.CallDetailsFooterViewHolder.DeleteCallDetailsListener; import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallbackActionListener; import com.android.dialer.calldetails.CallDetailsHeaderViewHolder.CallbackActionListener; import com.android.dialer.calllogutils.CallTypeHelper; import com.android.dialer.calllogutils.CallTypeHelper; import com.android.dialer.calllogutils.CallbackActionHelper; import com.android.dialer.calllogutils.CallbackActionHelper; Loading @@ -42,6 +43,7 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol private final DialerContact contact; private final DialerContact contact; private final CallbackActionListener callbackActionListener; private final CallbackActionListener callbackActionListener; private final CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener; private final CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener; private final DeleteCallDetailsListener deleteCallDetailsListener; private final CallTypeHelper callTypeHelper; private final CallTypeHelper callTypeHelper; private List<CallDetailsEntry> callDetailsEntries; private List<CallDetailsEntry> callDetailsEntries; Loading @@ -50,11 +52,13 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol @NonNull DialerContact contact, @NonNull DialerContact contact, @NonNull List<CallDetailsEntry> callDetailsEntries, @NonNull List<CallDetailsEntry> callDetailsEntries, CallbackActionListener callbackActionListener, CallbackActionListener callbackActionListener, CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener) { CallDetailsFooterViewHolder.ReportCallIdListener reportCallIdListener, DeleteCallDetailsListener deleteCallDetailsListener) { this.contact = Assert.isNotNull(contact); this.contact = Assert.isNotNull(contact); this.callDetailsEntries = callDetailsEntries; this.callDetailsEntries = callDetailsEntries; this.callbackActionListener = callbackActionListener; this.callbackActionListener = callbackActionListener; this.reportCallIdListener = reportCallIdListener; this.reportCallIdListener = reportCallIdListener; this.deleteCallDetailsListener = deleteCallDetailsListener; callTypeHelper = new CallTypeHelper(context.getResources(), DuoComponent.get(context).getDuo()); callTypeHelper = new CallTypeHelper(context.getResources(), DuoComponent.get(context).getDuo()); } } Loading @@ -70,7 +74,9 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol inflater.inflate(R.layout.call_details_entry, parent, false)); inflater.inflate(R.layout.call_details_entry, parent, false)); case FOOTER_VIEW_TYPE: case FOOTER_VIEW_TYPE: return new CallDetailsFooterViewHolder( return new CallDetailsFooterViewHolder( inflater.inflate(R.layout.call_details_footer, parent, false), reportCallIdListener); inflater.inflate(R.layout.call_details_footer, parent, false), reportCallIdListener, deleteCallDetailsListener); default: default: throw Assert.createIllegalStateFailException( throw Assert.createIllegalStateFailException( "No ViewHolder available for viewType: " + viewType); "No ViewHolder available for viewType: " + viewType); Loading