Loading java/com/android/dialer/calldetails/CallDetailsActivity.java +98 −9 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ package com.android.dialer.calldetails; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.app.LoaderManager.LoaderCallbacks; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; import android.provider.CallLog; Loading @@ -35,11 +38,13 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Toast; import com.android.dialer.CoalescedIds; import com.android.dialer.DialerPhoneNumber; import com.android.dialer.assisteddialing.ui.AssistedDialingSettingActivity; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutors; Loading @@ -62,6 +67,7 @@ import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.i18n.phonenumbers.PhoneNumberUtil; import java.lang.ref.WeakReference; Loading @@ -71,10 +77,12 @@ import java.util.Map; /** Displays the details of a specific call log entry. */ public class CallDetailsActivity extends AppCompatActivity { private static final int CALL_DETAILS_LOADER_ID = 0; public static final String EXTRA_PHONE_NUMBER = "phone_number"; public static final String EXTRA_HAS_ENRICHED_CALL_DATA = "has_enriched_call_data"; public static final String EXTRA_CALL_DETAILS_ENTRIES = "call_details_entries"; public static final String EXTRA_COALESCED_CALL_LOG_IDS = "coalesced_call_log_ids"; public static final String EXTRA_CONTACT = "contact"; public static final String EXTRA_CAN_REPORT_CALLER_ID = "can_report_caller_id"; private static final String EXTRA_CAN_SUPPORT_ASSISTED_DIALING = "can_support_assisted_dialing"; Loading @@ -93,23 +101,47 @@ public class CallDetailsActivity extends AppCompatActivity { private DialerContact contact; private CallDetailsAdapter adapter; // This will be present only when the activity is launched from the new call log UI, i.e., a list // of coalesced annotated call log IDs is included in the intent. private Optional<CoalescedIds> coalescedCallLogIds = Optional.absent(); public static boolean isLaunchIntent(Intent intent) { return intent.getComponent() != null && CallDetailsActivity.class.getName().equals(intent.getComponent().getClassName()); } /** * Returns an {@link Intent} for launching the {@link CallDetailsActivity} from the old call log * UI. */ public static Intent newInstance( Context context, @NonNull CallDetailsEntries details, @NonNull DialerContact contact, CallDetailsEntries details, DialerContact contact, boolean canReportCallerId, boolean canSupportAssistedDialing) { Assert.isNotNull(details); Assert.isNotNull(contact); Intent intent = new Intent(context, CallDetailsActivity.class); ProtoParsers.put(intent, EXTRA_CONTACT, Assert.isNotNull(contact)); ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, Assert.isNotNull(details)); intent.putExtra(EXTRA_CAN_REPORT_CALLER_ID, canReportCallerId); intent.putExtra(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, canSupportAssistedDialing); return intent; } /** * Returns an {@link Intent} for launching the {@link CallDetailsActivity} from the new call log * UI. */ public static Intent newInstance( Context context, CoalescedIds coalescedAnnotatedCallLogIds, DialerContact contact, boolean canReportCallerId, boolean canSupportAssistedDialing) { Intent intent = new Intent(context, CallDetailsActivity.class); ProtoParsers.put(intent, EXTRA_CONTACT, contact); ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, details); ProtoParsers.put(intent, EXTRA_CONTACT, Assert.isNotNull(contact)); ProtoParsers.put( intent, EXTRA_COALESCED_CALL_LOG_IDS, Assert.isNotNull(coalescedAnnotatedCallLogIds)); intent.putExtra(EXTRA_CAN_REPORT_CALLER_ID, canReportCallerId); intent.putExtra(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, canSupportAssistedDialing); return intent; Loading Loading @@ -166,10 +198,30 @@ public class CallDetailsActivity extends AppCompatActivity { } private void onHandleIntent(Intent intent) { boolean hasCallDetailsEntries = intent.hasExtra(EXTRA_CALL_DETAILS_ENTRIES); boolean hasCoalescedCallLogIds = intent.hasExtra(EXTRA_COALESCED_CALL_LOG_IDS); Assert.checkArgument( (hasCallDetailsEntries && !hasCoalescedCallLogIds) || (!hasCallDetailsEntries && hasCoalescedCallLogIds), "One and only one of EXTRA_CALL_DETAILS_ENTRIES and EXTRA_COALESCED_CALL_LOG_IDS " + "can be included in the intent."); contact = ProtoParsers.getTrusted(intent, EXTRA_CONTACT, DialerContact.getDefaultInstance()); if (hasCallDetailsEntries) { entries = ProtoParsers.getTrusted( intent, EXTRA_CALL_DETAILS_ENTRIES, CallDetailsEntries.getDefaultInstance()); } else { entries = CallDetailsEntries.getDefaultInstance(); coalescedCallLogIds = Optional.of( ProtoParsers.getTrusted( intent, EXTRA_COALESCED_CALL_LOG_IDS, CoalescedIds.getDefaultInstance())); getLoaderManager() .initLoader( CALL_DETAILS_LOADER_ID, /* args = */ null, new CallDetailsLoaderCallbacks(this)); } adapter = new CallDetailsAdapter( this /* context */, Loading @@ -191,6 +243,43 @@ public class CallDetailsActivity extends AppCompatActivity { super.onBackPressed(); } /** * {@link LoaderCallbacks} for {@link CallDetailsCursorLoader}, which loads call detail entries * from {@link AnnotatedCallLog}. */ private static final class CallDetailsLoaderCallbacks implements LoaderCallbacks<Cursor> { private final CallDetailsActivity activity; CallDetailsLoaderCallbacks(CallDetailsActivity callDetailsActivity) { this.activity = callDetailsActivity; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Assert.checkState(activity.coalescedCallLogIds.isPresent()); return new CallDetailsCursorLoader(activity, activity.coalescedCallLogIds.get()); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { updateCallDetailsEntries(CallDetailsCursorLoader.toCallDetailsEntries(data)); } @Override public void onLoaderReset(Loader<Cursor> loader) { updateCallDetailsEntries(CallDetailsEntries.getDefaultInstance()); } private void updateCallDetailsEntries(CallDetailsEntries newEntries) { activity.entries = newEntries; activity.adapter.updateCallDetailsEntries(newEntries.getEntriesList()); EnrichedCallComponent.get(activity) .getEnrichedCallManager() .requestAllHistoricalData(activity.contact.getNumber(), newEntries); } } /** Delete specified calls from the call log. */ private static class DeleteCallsTask extends AsyncTask<Void, Void, Void> { // Use a weak reference to hold the Activity so that there is no memory leak. Loading java/com/android/dialer/calldetails/CallDetailsAdapter.java +3 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,9 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol @Override public int getItemCount() { return callDetailsEntries.size() + 2; // Header + footer return callDetailsEntries.isEmpty() ? 0 : callDetailsEntries.size() + 2; // plus header and footer } void updateCallDetailsEntries(List<CallDetailsEntry> entries) { Loading java/com/android/dialer/calldetails/CallDetailsCursorLoader.java 0 → 100644 +139 −0 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.calldetails; import android.content.Context; import android.content.CursorLoader; import android.database.Cursor; import com.android.dialer.CoalescedIds; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.Assert; import com.android.dialer.duo.DuoConstants; /** * A {@link CursorLoader} that loads call detail entries from {@link AnnotatedCallLog} for {@link * CallDetailsActivity}. */ public final class CallDetailsCursorLoader extends CursorLoader { // Columns in AnnotatedCallLog that are needed to build a CallDetailsEntry proto. // Be sure to update (1) constants that store indexes of the elements and (2) method // toCallDetailsEntry(Cursor) when updating this array. public static final String[] COLUMNS_FOR_CALL_DETAILS = new String[] { AnnotatedCallLog._ID, AnnotatedCallLog.CALL_TYPE, AnnotatedCallLog.FEATURES, AnnotatedCallLog.TIMESTAMP, AnnotatedCallLog.DURATION, AnnotatedCallLog.DATA_USAGE, AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME }; // Indexes for COLUMNS_FOR_CALL_DETAILS private static final int ID = 0; private static final int CALL_TYPE = 1; private static final int FEATURES = 2; private static final int TIMESTAMP = 3; private static final int DURATION = 4; private static final int DATA_USAGE = 5; private static final int PHONE_ACCOUNT_COMPONENT_NAME = 6; CallDetailsCursorLoader(Context context, CoalescedIds coalescedIds) { super( context, AnnotatedCallLog.CONTENT_URI, COLUMNS_FOR_CALL_DETAILS, annotatedCallLogIdsSelection(coalescedIds), annotatedCallLogIdsSelectionArgs(coalescedIds), AnnotatedCallLog.TIMESTAMP + " DESC"); } /** * Build a string of the form "COLUMN_NAME IN (?, ?, ..., ?)", where COLUMN_NAME is the name of * the ID column in {@link AnnotatedCallLog}. * * <p>This string will be used as the {@code selection} parameter to initialize the loader. */ private static String annotatedCallLogIdsSelection(CoalescedIds coalescedIds) { // First, build a string of question marks ('?') separated by commas (','). StringBuilder questionMarks = new StringBuilder(); for (int i = 0; i < coalescedIds.getCoalescedIdCount(); i++) { if (i != 0) { questionMarks.append(", "); } questionMarks.append("?"); } return AnnotatedCallLog._ID + " IN (" + questionMarks + ")"; } /** * Returns a string that will be used as the {@code selectionArgs} parameter to initialize the * loader. */ private static String[] annotatedCallLogIdsSelectionArgs(CoalescedIds coalescedIds) { String[] args = new String[coalescedIds.getCoalescedIdCount()]; for (int i = 0; i < coalescedIds.getCoalescedIdCount(); i++) { args[i] = String.valueOf(coalescedIds.getCoalescedId(i)); } return args; } /** * Creates a new {@link CallDetailsEntries} from the entire data set loaded by this loader. * * @param cursor A cursor pointing to the data set loaded by this loader. The caller must ensure * the cursor is not null and the data set it points to is not empty. * @return A {@link CallDetailsEntries} proto. */ static CallDetailsEntries toCallDetailsEntries(Cursor cursor) { Assert.isNotNull(cursor); Assert.checkArgument(cursor.moveToFirst()); CallDetailsEntries.Builder entries = CallDetailsEntries.newBuilder(); do { entries.addEntries(toCallDetailsEntry(cursor)); } while (cursor.moveToNext()); return entries.build(); } /** Creates a new {@link CallDetailsEntry} from the provided cursor using its current position. */ private static CallDetailsEntry toCallDetailsEntry(Cursor cursor) { CallDetailsEntry.Builder entry = CallDetailsEntry.newBuilder(); entry .setCallId(cursor.getLong(ID)) .setCallType(cursor.getInt(CALL_TYPE)) .setFeatures(cursor.getInt(FEATURES)) .setDate(cursor.getLong(TIMESTAMP)) .setDuration(cursor.getLong(DURATION)) .setDataUsage(cursor.getLong(DATA_USAGE)); String phoneAccountComponentName = cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME); entry.setIsDuoCall( DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME .flattenToString() .equals(phoneAccountComponentName)); return entry.build(); } } java/com/android/dialer/calllog/ui/menu/Modules.java +6 −8 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.provider.ContactsContract; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import com.android.dialer.calldetails.CallDetailsActivity; import com.android.dialer.calldetails.CallDetailsEntries; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.calllog.model.CoalescedRow; import com.android.dialer.calllogutils.PhoneAccountUtils; Loading Loading @@ -65,7 +64,7 @@ final class Modules { // TODO(zachh): Revisit if DialerContact is the best thing to pass to CallDetails; could // it use a ContactPrimaryActionInfo instead? addModuleForAccessingCallDetails(context, createDialerContactFromRow(row), modules); addModuleForAccessingCallDetails(context, row, modules); return modules; } Loading Loading @@ -182,10 +181,9 @@ final class Modules { } private static void addModuleForAccessingCallDetails( Context context, DialerContact dialerContact, List<ContactActionModule> modules) { // TODO(zachh): Load CallDetailsEntries and canReportInaccurateNumber in // CallDetailsActivity (see also isPeopleApiSource(sourceType)). CallDetailsEntries callDetailsEntries = CallDetailsEntries.getDefaultInstance(); Context context, CoalescedRow row, List<ContactActionModule> modules) { // TODO(zachh): Load canReportInaccurateNumber in CallDetailsActivity // (see also isPeopleApiSource(sourceType)). boolean canReportInaccurateNumber = false; boolean canSupportAssistedDialing = false; // TODO(zachh): Properly set value. Loading @@ -194,8 +192,8 @@ final class Modules { context, CallDetailsActivity.newInstance( context, callDetailsEntries, dialerContact, row.coalescedIds(), createDialerContactFromRow(row), canReportInaccurateNumber, canSupportAssistedDialing), R.string.call_details_menu_label, Loading Loading
java/com/android/dialer/calldetails/CallDetailsActivity.java +98 −9 Original line number Diff line number Diff line Loading @@ -19,9 +19,12 @@ package com.android.dialer.calldetails; import android.Manifest.permission; import android.annotation.SuppressLint; import android.app.Activity; import android.app.LoaderManager.LoaderCallbacks; import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.Loader; import android.database.Cursor; import android.os.AsyncTask; import android.os.Bundle; import android.provider.CallLog; Loading @@ -35,11 +38,13 @@ import android.support.v7.widget.RecyclerView; import android.support.v7.widget.Toolbar; import android.view.View; import android.widget.Toast; import com.android.dialer.CoalescedIds; import com.android.dialer.DialerPhoneNumber; import com.android.dialer.assisteddialing.ui.AssistedDialingSettingActivity; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.callintent.CallIntentBuilder; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.AsyncTaskExecutors; Loading @@ -62,6 +67,7 @@ import com.android.dialer.phonenumberproto.DialerPhoneNumberUtil; import com.android.dialer.postcall.PostCall; import com.android.dialer.precall.PreCall; import com.android.dialer.protos.ProtoParsers; import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.i18n.phonenumbers.PhoneNumberUtil; import java.lang.ref.WeakReference; Loading @@ -71,10 +77,12 @@ import java.util.Map; /** Displays the details of a specific call log entry. */ public class CallDetailsActivity extends AppCompatActivity { private static final int CALL_DETAILS_LOADER_ID = 0; public static final String EXTRA_PHONE_NUMBER = "phone_number"; public static final String EXTRA_HAS_ENRICHED_CALL_DATA = "has_enriched_call_data"; public static final String EXTRA_CALL_DETAILS_ENTRIES = "call_details_entries"; public static final String EXTRA_COALESCED_CALL_LOG_IDS = "coalesced_call_log_ids"; public static final String EXTRA_CONTACT = "contact"; public static final String EXTRA_CAN_REPORT_CALLER_ID = "can_report_caller_id"; private static final String EXTRA_CAN_SUPPORT_ASSISTED_DIALING = "can_support_assisted_dialing"; Loading @@ -93,23 +101,47 @@ public class CallDetailsActivity extends AppCompatActivity { private DialerContact contact; private CallDetailsAdapter adapter; // This will be present only when the activity is launched from the new call log UI, i.e., a list // of coalesced annotated call log IDs is included in the intent. private Optional<CoalescedIds> coalescedCallLogIds = Optional.absent(); public static boolean isLaunchIntent(Intent intent) { return intent.getComponent() != null && CallDetailsActivity.class.getName().equals(intent.getComponent().getClassName()); } /** * Returns an {@link Intent} for launching the {@link CallDetailsActivity} from the old call log * UI. */ public static Intent newInstance( Context context, @NonNull CallDetailsEntries details, @NonNull DialerContact contact, CallDetailsEntries details, DialerContact contact, boolean canReportCallerId, boolean canSupportAssistedDialing) { Assert.isNotNull(details); Assert.isNotNull(contact); Intent intent = new Intent(context, CallDetailsActivity.class); ProtoParsers.put(intent, EXTRA_CONTACT, Assert.isNotNull(contact)); ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, Assert.isNotNull(details)); intent.putExtra(EXTRA_CAN_REPORT_CALLER_ID, canReportCallerId); intent.putExtra(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, canSupportAssistedDialing); return intent; } /** * Returns an {@link Intent} for launching the {@link CallDetailsActivity} from the new call log * UI. */ public static Intent newInstance( Context context, CoalescedIds coalescedAnnotatedCallLogIds, DialerContact contact, boolean canReportCallerId, boolean canSupportAssistedDialing) { Intent intent = new Intent(context, CallDetailsActivity.class); ProtoParsers.put(intent, EXTRA_CONTACT, contact); ProtoParsers.put(intent, EXTRA_CALL_DETAILS_ENTRIES, details); ProtoParsers.put(intent, EXTRA_CONTACT, Assert.isNotNull(contact)); ProtoParsers.put( intent, EXTRA_COALESCED_CALL_LOG_IDS, Assert.isNotNull(coalescedAnnotatedCallLogIds)); intent.putExtra(EXTRA_CAN_REPORT_CALLER_ID, canReportCallerId); intent.putExtra(EXTRA_CAN_SUPPORT_ASSISTED_DIALING, canSupportAssistedDialing); return intent; Loading Loading @@ -166,10 +198,30 @@ public class CallDetailsActivity extends AppCompatActivity { } private void onHandleIntent(Intent intent) { boolean hasCallDetailsEntries = intent.hasExtra(EXTRA_CALL_DETAILS_ENTRIES); boolean hasCoalescedCallLogIds = intent.hasExtra(EXTRA_COALESCED_CALL_LOG_IDS); Assert.checkArgument( (hasCallDetailsEntries && !hasCoalescedCallLogIds) || (!hasCallDetailsEntries && hasCoalescedCallLogIds), "One and only one of EXTRA_CALL_DETAILS_ENTRIES and EXTRA_COALESCED_CALL_LOG_IDS " + "can be included in the intent."); contact = ProtoParsers.getTrusted(intent, EXTRA_CONTACT, DialerContact.getDefaultInstance()); if (hasCallDetailsEntries) { entries = ProtoParsers.getTrusted( intent, EXTRA_CALL_DETAILS_ENTRIES, CallDetailsEntries.getDefaultInstance()); } else { entries = CallDetailsEntries.getDefaultInstance(); coalescedCallLogIds = Optional.of( ProtoParsers.getTrusted( intent, EXTRA_COALESCED_CALL_LOG_IDS, CoalescedIds.getDefaultInstance())); getLoaderManager() .initLoader( CALL_DETAILS_LOADER_ID, /* args = */ null, new CallDetailsLoaderCallbacks(this)); } adapter = new CallDetailsAdapter( this /* context */, Loading @@ -191,6 +243,43 @@ public class CallDetailsActivity extends AppCompatActivity { super.onBackPressed(); } /** * {@link LoaderCallbacks} for {@link CallDetailsCursorLoader}, which loads call detail entries * from {@link AnnotatedCallLog}. */ private static final class CallDetailsLoaderCallbacks implements LoaderCallbacks<Cursor> { private final CallDetailsActivity activity; CallDetailsLoaderCallbacks(CallDetailsActivity callDetailsActivity) { this.activity = callDetailsActivity; } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { Assert.checkState(activity.coalescedCallLogIds.isPresent()); return new CallDetailsCursorLoader(activity, activity.coalescedCallLogIds.get()); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { updateCallDetailsEntries(CallDetailsCursorLoader.toCallDetailsEntries(data)); } @Override public void onLoaderReset(Loader<Cursor> loader) { updateCallDetailsEntries(CallDetailsEntries.getDefaultInstance()); } private void updateCallDetailsEntries(CallDetailsEntries newEntries) { activity.entries = newEntries; activity.adapter.updateCallDetailsEntries(newEntries.getEntriesList()); EnrichedCallComponent.get(activity) .getEnrichedCallManager() .requestAllHistoricalData(activity.contact.getNumber(), newEntries); } } /** Delete specified calls from the call log. */ private static class DeleteCallsTask extends AsyncTask<Void, Void, Void> { // Use a weak reference to hold the Activity so that there is no memory leak. Loading
java/com/android/dialer/calldetails/CallDetailsAdapter.java +3 −1 Original line number Diff line number Diff line Loading @@ -115,7 +115,9 @@ final class CallDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHol @Override public int getItemCount() { return callDetailsEntries.size() + 2; // Header + footer return callDetailsEntries.isEmpty() ? 0 : callDetailsEntries.size() + 2; // plus header and footer } void updateCallDetailsEntries(List<CallDetailsEntry> entries) { Loading
java/com/android/dialer/calldetails/CallDetailsCursorLoader.java 0 → 100644 +139 −0 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.calldetails; import android.content.Context; import android.content.CursorLoader; import android.database.Cursor; import com.android.dialer.CoalescedIds; import com.android.dialer.calldetails.CallDetailsEntries.CallDetailsEntry; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; import com.android.dialer.common.Assert; import com.android.dialer.duo.DuoConstants; /** * A {@link CursorLoader} that loads call detail entries from {@link AnnotatedCallLog} for {@link * CallDetailsActivity}. */ public final class CallDetailsCursorLoader extends CursorLoader { // Columns in AnnotatedCallLog that are needed to build a CallDetailsEntry proto. // Be sure to update (1) constants that store indexes of the elements and (2) method // toCallDetailsEntry(Cursor) when updating this array. public static final String[] COLUMNS_FOR_CALL_DETAILS = new String[] { AnnotatedCallLog._ID, AnnotatedCallLog.CALL_TYPE, AnnotatedCallLog.FEATURES, AnnotatedCallLog.TIMESTAMP, AnnotatedCallLog.DURATION, AnnotatedCallLog.DATA_USAGE, AnnotatedCallLog.PHONE_ACCOUNT_COMPONENT_NAME }; // Indexes for COLUMNS_FOR_CALL_DETAILS private static final int ID = 0; private static final int CALL_TYPE = 1; private static final int FEATURES = 2; private static final int TIMESTAMP = 3; private static final int DURATION = 4; private static final int DATA_USAGE = 5; private static final int PHONE_ACCOUNT_COMPONENT_NAME = 6; CallDetailsCursorLoader(Context context, CoalescedIds coalescedIds) { super( context, AnnotatedCallLog.CONTENT_URI, COLUMNS_FOR_CALL_DETAILS, annotatedCallLogIdsSelection(coalescedIds), annotatedCallLogIdsSelectionArgs(coalescedIds), AnnotatedCallLog.TIMESTAMP + " DESC"); } /** * Build a string of the form "COLUMN_NAME IN (?, ?, ..., ?)", where COLUMN_NAME is the name of * the ID column in {@link AnnotatedCallLog}. * * <p>This string will be used as the {@code selection} parameter to initialize the loader. */ private static String annotatedCallLogIdsSelection(CoalescedIds coalescedIds) { // First, build a string of question marks ('?') separated by commas (','). StringBuilder questionMarks = new StringBuilder(); for (int i = 0; i < coalescedIds.getCoalescedIdCount(); i++) { if (i != 0) { questionMarks.append(", "); } questionMarks.append("?"); } return AnnotatedCallLog._ID + " IN (" + questionMarks + ")"; } /** * Returns a string that will be used as the {@code selectionArgs} parameter to initialize the * loader. */ private static String[] annotatedCallLogIdsSelectionArgs(CoalescedIds coalescedIds) { String[] args = new String[coalescedIds.getCoalescedIdCount()]; for (int i = 0; i < coalescedIds.getCoalescedIdCount(); i++) { args[i] = String.valueOf(coalescedIds.getCoalescedId(i)); } return args; } /** * Creates a new {@link CallDetailsEntries} from the entire data set loaded by this loader. * * @param cursor A cursor pointing to the data set loaded by this loader. The caller must ensure * the cursor is not null and the data set it points to is not empty. * @return A {@link CallDetailsEntries} proto. */ static CallDetailsEntries toCallDetailsEntries(Cursor cursor) { Assert.isNotNull(cursor); Assert.checkArgument(cursor.moveToFirst()); CallDetailsEntries.Builder entries = CallDetailsEntries.newBuilder(); do { entries.addEntries(toCallDetailsEntry(cursor)); } while (cursor.moveToNext()); return entries.build(); } /** Creates a new {@link CallDetailsEntry} from the provided cursor using its current position. */ private static CallDetailsEntry toCallDetailsEntry(Cursor cursor) { CallDetailsEntry.Builder entry = CallDetailsEntry.newBuilder(); entry .setCallId(cursor.getLong(ID)) .setCallType(cursor.getInt(CALL_TYPE)) .setFeatures(cursor.getInt(FEATURES)) .setDate(cursor.getLong(TIMESTAMP)) .setDuration(cursor.getLong(DURATION)) .setDataUsage(cursor.getLong(DATA_USAGE)); String phoneAccountComponentName = cursor.getString(PHONE_ACCOUNT_COMPONENT_NAME); entry.setIsDuoCall( DuoConstants.PHONE_ACCOUNT_COMPONENT_NAME .flattenToString() .equals(phoneAccountComponentName)); return entry.build(); } }
java/com/android/dialer/calllog/ui/menu/Modules.java +6 −8 Original line number Diff line number Diff line Loading @@ -24,7 +24,6 @@ import android.provider.ContactsContract; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import com.android.dialer.calldetails.CallDetailsActivity; import com.android.dialer.calldetails.CallDetailsEntries; import com.android.dialer.callintent.CallInitiationType; import com.android.dialer.calllog.model.CoalescedRow; import com.android.dialer.calllogutils.PhoneAccountUtils; Loading Loading @@ -65,7 +64,7 @@ final class Modules { // TODO(zachh): Revisit if DialerContact is the best thing to pass to CallDetails; could // it use a ContactPrimaryActionInfo instead? addModuleForAccessingCallDetails(context, createDialerContactFromRow(row), modules); addModuleForAccessingCallDetails(context, row, modules); return modules; } Loading Loading @@ -182,10 +181,9 @@ final class Modules { } private static void addModuleForAccessingCallDetails( Context context, DialerContact dialerContact, List<ContactActionModule> modules) { // TODO(zachh): Load CallDetailsEntries and canReportInaccurateNumber in // CallDetailsActivity (see also isPeopleApiSource(sourceType)). CallDetailsEntries callDetailsEntries = CallDetailsEntries.getDefaultInstance(); Context context, CoalescedRow row, List<ContactActionModule> modules) { // TODO(zachh): Load canReportInaccurateNumber in CallDetailsActivity // (see also isPeopleApiSource(sourceType)). boolean canReportInaccurateNumber = false; boolean canSupportAssistedDialing = false; // TODO(zachh): Properly set value. Loading @@ -194,8 +192,8 @@ final class Modules { context, CallDetailsActivity.newInstance( context, callDetailsEntries, dialerContact, row.coalescedIds(), createDialerContactFromRow(row), canReportInaccurateNumber, canSupportAssistedDialing), R.string.call_details_menu_label, Loading