diff options
Diffstat (limited to 'java/com/android/dialer/calllog')
11 files changed, 104 insertions, 61 deletions
diff --git a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java index 32c278838..fb3700efe 100644 --- a/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java +++ b/java/com/android/dialer/calllog/RefreshAnnotatedCallLogWorker.java @@ -156,8 +156,7 @@ public class RefreshAnnotatedCallLogWorker { for (CallLogDataSource dataSource : dataSources.getDataSourcesIncludingSystemCallLog()) { ListenableFuture<Boolean> dataSourceDirty = dataSource.isDirty(); isDirtyFutures.add(dataSourceDirty); - String eventName = - String.format(Metrics.IS_DIRTY_TEMPLATE, dataSource.getClass().getSimpleName()); + String eventName = String.format(Metrics.IS_DIRTY_TEMPLATE, dataSource.getLoggingName()); futureTimer.applyTiming(dataSourceDirty, eventName, LogCatMode.LOG_VALUES); } // Simultaneously invokes isDirty on all data sources, returning as soon as one returns true. @@ -242,7 +241,7 @@ public class RefreshAnnotatedCallLogWorker { private static String eventNameForFill(CallLogDataSource dataSource, boolean isBuilt) { return String.format( !isBuilt ? Metrics.INITIAL_FILL_TEMPLATE : Metrics.FILL_TEMPLATE, - dataSource.getClass().getSimpleName()); + dataSource.getLoggingName()); } private static String eventNameForOverallFill(boolean isBuilt) { @@ -255,7 +254,7 @@ public class RefreshAnnotatedCallLogWorker { !isBuilt ? Metrics.INITIAL_ON_SUCCESSFUL_FILL_TEMPLATE : Metrics.ON_SUCCESSFUL_FILL_TEMPLATE, - dataSource.getClass().getSimpleName()); + dataSource.getLoggingName()); } private static String eventNameForOverallOnSuccessfulFill(boolean isBuilt) { diff --git a/java/com/android/dialer/calllog/database/contract/number_attributes.proto b/java/com/android/dialer/calllog/database/contract/number_attributes.proto index f42974d36..2c46d1b12 100644 --- a/java/com/android/dialer/calllog/database/contract/number_attributes.proto +++ b/java/com/android/dialer/calllog/database/contract/number_attributes.proto @@ -24,7 +24,7 @@ package com.android.dialer; import "java/com/android/dialer/logging/contact_source.proto"; // Information related to the phone number of the call. -// Next ID: 14 +// Next ID: 15 message NumberAttributes { // The name (which may be a person's name or business name, but not a number) // formatted exactly as it should appear to the user. If the user's locale or @@ -74,4 +74,7 @@ message NumberAttributes { // Description of the number's geolocation (e.g., "Mountain View, CA"). // This string is for display purpose only. optional string geolocation = 13; + + // Whether the number is an emergency number. + optional bool is_emergency_number = 14; }
\ No newline at end of file diff --git a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java index f6796c767..75f06d5f6 100644 --- a/java/com/android/dialer/calllog/datasources/CallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/CallLogDataSource.java @@ -113,4 +113,11 @@ public interface CallLogDataSource { */ @MainThread ListenableFuture<Void> clearData(); + + /** + * The name of this daa source for logging purposes. This is generally the same as the class name + * (but should not use methods from {@link Class} because the class names are generally obfuscated + * by Proguard. + */ + String getLoggingName(); } diff --git a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java index 0de987308..66d29a7ef 100644 --- a/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java +++ b/java/com/android/dialer/calllog/datasources/phonelookup/PhoneLookupDataSource.java @@ -320,6 +320,11 @@ public final class PhoneLookupDataSource implements CallLogDataSource { MoreExecutors.directExecutor()); } + @Override + public String getLoggingName() { + return "PhoneLookupDataSource"; + } + private static ImmutableSet<DialerPhoneNumber> queryDistinctDialerPhoneNumbersFromAnnotatedCallLog(Context appContext) { ImmutableSet.Builder<DialerPhoneNumber> numbers = ImmutableSet.builder(); diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index b5067daac..a08b50eb8 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -148,6 +148,11 @@ public class SystemCallLogDataSource implements CallLogDataSource { } @Override + public String getLoggingName() { + return "SystemCallLogDataSource"; + } + + @Override public ListenableFuture<Boolean> isDirty() { return backgroundExecutorService.submit(this::isDirtyInternal); } diff --git a/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java index ab9288a1e..7a230220e 100644 --- a/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java +++ b/java/com/android/dialer/calllog/datasources/voicemail/VoicemailDataSource.java @@ -121,4 +121,9 @@ public class VoicemailDataSource implements CallLogDataSource { public ListenableFuture<Void> clearData() { return Futures.immediateFuture(null); } + + @Override + public String getLoggingName() { + return "VoicemailDataSource"; + } } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java index f373a7c69..7fd8132aa 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogAdapter.java @@ -15,6 +15,7 @@ */ package com.android.dialer.calllog.ui; +import android.app.Activity; import android.content.Context; import android.content.SharedPreferences; import android.database.Cursor; @@ -72,7 +73,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { } private final Clock clock; - private final Context context; + private final Activity activity; private final RealtimeRowProcessor realtimeRowProcessor; private final PopCounts popCounts = new PopCounts(); private final SharedPreferences sharedPref; @@ -93,12 +94,12 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { /** Position of the "Older" header. Null when it should not be displayed. */ @Nullable private Integer olderHeaderPosition; - NewCallLogAdapter(Context context, Cursor cursor, Clock clock) { - this.context = context; + NewCallLogAdapter(Activity activity, Cursor cursor, Clock clock) { + this.activity = activity; this.cursor = cursor; this.clock = clock; - this.realtimeRowProcessor = CallLogUiComponent.get(context).realtimeRowProcessor(); - this.sharedPref = StorageComponent.get(context).unencryptedSharedPrefs(); + this.realtimeRowProcessor = CallLogUiComponent.get(activity).realtimeRowProcessor(); + this.sharedPref = StorageComponent.get(activity).unencryptedSharedPrefs(); this.onScrollListenerForRecordingDuoDisclosureFirstViewTime = new OnScrollListenerForRecordingDuoDisclosureFirstViewTime(sharedPref, clock); @@ -175,8 +176,8 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { // Don't show the Duo disclosure card if // (1) Duo integration is not enabled on the device, or // (2) Duo is not activated. - Duo duo = DuoComponent.get(context).getDuo(); - if (!duo.isEnabled(context) || !duo.isActivated(context)) { + Duo duo = DuoComponent.get(activity).getDuo(); + if (!duo.isEnabled(activity) || !duo.isActivated(activity)) { return false; } @@ -218,7 +219,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { switch (viewType) { case RowType.DUO_DISCLOSURE_CARD: return new DuoDisclosureCardViewHolder( - LayoutInflater.from(context) + LayoutInflater.from(activity) .inflate( R.layout.new_call_log_duo_disclosure_card, viewGroup, @@ -227,11 +228,12 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { case RowType.HEADER_YESTERDAY: case RowType.HEADER_OLDER: return new HeaderViewHolder( - LayoutInflater.from(context) + LayoutInflater.from(activity) .inflate(R.layout.new_call_log_header, viewGroup, /* attachToRoot = */ false)); case RowType.CALL_LOG_ENTRY: return new NewCallLogViewHolder( - LayoutInflater.from(context) + activity, + LayoutInflater.from(activity) .inflate(R.layout.new_call_log_entry, viewGroup, /* attachToRoot = */ false), clock, realtimeRowProcessor, @@ -249,7 +251,7 @@ final class NewCallLogAdapter extends RecyclerView.Adapter<ViewHolder> { ((DuoDisclosureCardViewHolder) viewHolder) .setDismissListener( unused -> { - StorageComponent.get(context) + StorageComponent.get(activity) .unencryptedSharedPrefs() .edit() .putBoolean(SHARED_PREF_KEY_DUO_DISCLOSURE_DISMISSED, true) diff --git a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java index 0f1c2510a..bc5750770 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogFragment.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogFragment.java @@ -15,6 +15,7 @@ */ package com.android.dialer.calllog.ui; +import android.app.Activity; import android.database.Cursor; import android.os.Bundle; import android.support.annotation.Nullable; @@ -30,6 +31,7 @@ import android.view.View; import android.view.ViewGroup; import com.android.dialer.calllog.CallLogComponent; import com.android.dialer.calllog.RefreshAnnotatedCallLogReceiver; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import com.android.dialer.common.concurrent.DefaultFutureCallback; import com.android.dialer.common.concurrent.ThreadUtil; @@ -229,8 +231,11 @@ public final class NewCallLogFragment extends Fragment implements LoaderCallback // TODO(zachh): Handle empty cursor by showing empty view. if (recyclerView.getAdapter() == null) { recyclerView.setLayoutManager(new LinearLayoutManager(getContext())); + // Note: It's not clear if this callback can be invoked when there's no associated activity, + // but if crashes are observed here it may be possible to use getContext() instead. + Activity activity = Assert.isNotNull(getActivity()); recyclerView.setAdapter( - new NewCallLogAdapter(getContext(), newCursor, System::currentTimeMillis)); + new NewCallLogAdapter(activity, newCursor, System::currentTimeMillis)); } else { ((NewCallLogAdapter) recyclerView.getAdapter()).updateCursor(newCursor); } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java index c02d80ede..5f3cd96c4 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java @@ -72,9 +72,13 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder { private long currentRowId; NewCallLogViewHolder( - View view, Clock clock, RealtimeRowProcessor realtimeRowProcessor, PopCounts popCounts) { + Activity activity, + View view, + Clock clock, + RealtimeRowProcessor realtimeRowProcessor, + PopCounts popCounts) { super(view); - this.activity = (Activity) view.getContext(); + this.activity = activity; contactPhotoView = view.findViewById(R.id.contact_photo_view); primaryTextView = view.findViewById(R.id.primary_text); callCountTextView = view.findViewById(R.id.call_count); diff --git a/java/com/android/dialer/calllog/ui/menu/Modules.java b/java/com/android/dialer/calllog/ui/menu/Modules.java index b06e0fb1a..cfeca1059 100644 --- a/java/com/android/dialer/calllog/ui/menu/Modules.java +++ b/java/com/android/dialer/calllog/ui/menu/Modules.java @@ -126,6 +126,7 @@ final class Modules { .setCanSupportAssistedDialing(canSupportAssistedDialing(row)) .setCanSupportCarrierVideoCall(row.getNumberAttributes().getCanSupportCarrierVideoCall()) .setIsBlocked(row.getNumberAttributes().getIsBlocked()) + .setIsEmergencyNumber(row.getNumberAttributes().getIsEmergencyNumber()) .setIsSpam(row.getNumberAttributes().getIsSpam()) .setIsVoicemailCall(row.getIsVoicemailCall()) .setContactSource(row.getNumberAttributes().getContactSource()) diff --git a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml index e3052c097..2fc8e7bb8 100644 --- a/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml +++ b/java/com/android/dialer/calllog/ui/res/layout/new_call_log_entry.xml @@ -17,6 +17,7 @@ <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:minHeight="72dp"> @@ -29,22 +30,34 @@ android:layout_marginEnd="10dp" android:layout_centerVertical="true"/> - <!-- The frame layout is necessary to avoid clipping the icons and ellipsize the text when the - content is too wide to fit. - --> - <FrameLayout - android:id="@+id/primary_row" + <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" + android:layout_marginTop="14dp" android:layout_toEndOf="@+id/contact_photo_view" - android:layout_toStartOf="@+id/menu_button"> + android:layout_toStartOf="@+id/menu_button" + android:orientation="vertical"> + <!-- 1st row: primary info --> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginTop="14dp" android:orientation="horizontal"> + <!-- + Important note: + + The following TextView is the only widget that defines a weight in the containing + LinearLayout, of which the purpose is to avoid pushing the widgets after it out of the + boundary when the text is too long. + + Generally it is more efficient to assign a width/height of 0dp so that the TextView does + not have to measure its own size since it will absorb all the remaining space anyway. + + However, as the TextView is part of an entry in the call log's RecyclerView, we must set + layout_width to "wrap_content" so that the TextView can adjust its size when recycled for + text of different lengths. + --> <TextView android:id="@+id/primary_text" style="@style/PrimaryText" @@ -54,32 +67,29 @@ android:layout_marginEnd="6dp" android:ellipsize="end" android:lineSpacingMultiplier="1.5" - android:singleLine="true"/> - + android:singleLine="true" + tools:ignore="InefficientWeight"/> <ImageView android:id="@+id/hd_icon" android:layout_width="wrap_content" android:layout_height="18dp" android:layout_gravity="center_vertical" - android:src="@drawable/quantum_ic_hd_vd_theme_24" - /> + android:src="@drawable/quantum_ic_hd_vd_theme_24"/> <ImageView android:id="@+id/wifi_icon" android:layout_width="wrap_content" android:layout_height="18dp" android:layout_gravity="center_vertical" - android:src="@drawable/quantum_ic_signal_wifi_4_bar_vd_theme_24" - /> + android:src="@drawable/quantum_ic_signal_wifi_4_bar_vd_theme_24"/> <ImageView android:id="@+id/assisted_dial_icon" android:layout_width="wrap_content" android:layout_height="18dp" android:layout_gravity="center_vertical" - android:src="@drawable/quantum_ic_language_vd_theme_24" - /> + android:src="@drawable/quantum_ic_language_vd_theme_24"/> <TextView android:id="@+id/call_count" @@ -90,43 +100,40 @@ android:lineSpacingMultiplier="1.5"/> </LinearLayout> - </FrameLayout> - - <LinearLayout - android:id="@+id/secondary_row" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@+id/primary_row" - android:layout_toEndOf="@+id/contact_photo_view" - android:orientation="horizontal"> - <ImageView - android:id="@+id/call_type_icon" + <!-- 2nd row: secondary info --> + <LinearLayout android:layout_width="wrap_content" - android:layout_height="18dp" - android:layout_gravity="center_vertical" - /> + android:layout_height="wrap_content" + android:orientation="horizontal"> + <ImageView + android:id="@+id/call_type_icon" + android:layout_width="wrap_content" + android:layout_height="18dp" + android:layout_gravity="center_vertical"/> + + <TextView + android:id="@+id/secondary_text" + style="@style/SecondaryText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:ellipsize="end" + android:lineSpacingMultiplier="1.4" + android:singleLine="true"/> + + </LinearLayout> + + <!-- 3rd row: phone account info --> <TextView - android:id="@+id/secondary_text" + android:id="@+id/phone_account" style="@style/SecondaryText" android:layout_width="wrap_content" android:layout_height="wrap_content" android:ellipsize="end" - android:lineSpacingMultiplier="1.4" android:singleLine="true"/> - </LinearLayout> - <TextView - android:id="@+id/phone_account" - style="@style/SecondaryText" - android:layout_width="wrap_content" - android:layout_height="wrap_content" - android:layout_below="@+id/secondary_row" - android:layout_toEndOf="@+id/contact_photo_view" - android:ellipsize="end" - android:singleLine="true" - android:visibility="visible"/> + </LinearLayout> <ImageView android:id="@+id/menu_button" |