From 01a964d7fbba63c670062ffca9a0ebe30cdcb1ff Mon Sep 17 00:00:00 2001 From: yueg Date: Tue, 3 Oct 2017 15:25:41 -0700 Subject: Make incoming and ongoing call notification foreground and highest priority. Use startForeground()/stopForeground() for posting notification instead of NotificationManager.notify()/cancel(). It makes incoming and ongoing notification foreground and not able to snooze. It also colorize ongoing call notification for Android O, since we already setColorized(). Use setPriority(Notification.PRIORITY_MAX) for pre-O, and NotificationManager.IMPORTANCE_MAX for O. It makes incoming and ongoing notification stay on the top. Test: StatusBarNotifierTest*2 PiperOrigin-RevId: 170924163 Change-Id: Iab1415b0161a4623a1ccf52d3948f32b6f93eeb2 --- .../notification/NotificationChannelManager.java | 2 +- .../incallui/NotificationBroadcastReceiver.java | 28 +++++++-------- java/com/android/incallui/StatusBarNotifier.java | 40 +++++++--------------- java/com/android/incallui/call/TelecomAdapter.java | 22 ++++++++++++ 4 files changed, 49 insertions(+), 43 deletions(-) (limited to 'java') diff --git a/java/com/android/dialer/notification/NotificationChannelManager.java b/java/com/android/dialer/notification/NotificationChannelManager.java index 790aac36f..93caed503 100644 --- a/java/com/android/dialer/notification/NotificationChannelManager.java +++ b/java/com/android/dialer/notification/NotificationChannelManager.java @@ -133,7 +133,7 @@ public final class NotificationChannelManager { new NotificationChannel( NotificationChannelId.ONGOING_CALL, context.getText(R.string.notification_channel_ongoing_call), - NotificationManager.IMPORTANCE_DEFAULT); + NotificationManager.IMPORTANCE_MAX); channel.setShowBadge(false); channel.enableLights(false); channel.enableVibration(false); diff --git a/java/com/android/incallui/NotificationBroadcastReceiver.java b/java/com/android/incallui/NotificationBroadcastReceiver.java index f83f84dbb..52d01f5c4 100644 --- a/java/com/android/incallui/NotificationBroadcastReceiver.java +++ b/java/com/android/incallui/NotificationBroadcastReceiver.java @@ -72,19 +72,19 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { // TODO: Commands of this nature should exist in the CallList. if (action.equals(ACTION_ANSWER_VIDEO_INCOMING_CALL)) { - answerIncomingCall(context, VideoProfile.STATE_BIDIRECTIONAL); + answerIncomingCall(VideoProfile.STATE_BIDIRECTIONAL); } else if (action.equals(ACTION_ANSWER_VOICE_INCOMING_CALL)) { - answerIncomingCall(context, VideoProfile.STATE_AUDIO_ONLY); + answerIncomingCall(VideoProfile.STATE_AUDIO_ONLY); } else if (action.equals(ACTION_DECLINE_INCOMING_CALL)) { Logger.get(context) .logImpression(DialerImpression.Type.REJECT_INCOMING_CALL_FROM_NOTIFICATION); - declineIncomingCall(context); + declineIncomingCall(); } else if (action.equals(ACTION_HANG_UP_ONGOING_CALL)) { - hangUpOngoingCall(context); + hangUpOngoingCall(); } else if (action.equals(ACTION_ACCEPT_VIDEO_UPGRADE_REQUEST)) { acceptUpgradeRequest(context); } else if (action.equals(ACTION_DECLINE_VIDEO_UPGRADE_REQUEST)) { - declineUpgradeRequest(context); + declineUpgradeRequest(); } else if (action.equals(ACTION_PULL_EXTERNAL_CALL)) { context.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); int notificationId = intent.getIntExtra(EXTRA_NOTIFICATION_ID, -1); @@ -99,7 +99,7 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { private void acceptUpgradeRequest(Context context) { CallList callList = InCallPresenter.getInstance().getCallList(); if (callList == null) { - StatusBarNotifier.clearAllCallNotifications(context); + StatusBarNotifier.clearAllCallNotifications(); LogUtil.e("NotificationBroadcastReceiver.acceptUpgradeRequest", "call list is empty"); } else { DialerCall call = callList.getVideoUpgradeRequestCall(); @@ -109,10 +109,10 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { } } - private void declineUpgradeRequest(Context context) { + private void declineUpgradeRequest() { CallList callList = InCallPresenter.getInstance().getCallList(); if (callList == null) { - StatusBarNotifier.clearAllCallNotifications(context); + StatusBarNotifier.clearAllCallNotifications(); LogUtil.e("NotificationBroadcastReceiver.declineUpgradeRequest", "call list is empty"); } else { DialerCall call = callList.getVideoUpgradeRequestCall(); @@ -122,10 +122,10 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { } } - private void hangUpOngoingCall(Context context) { + private void hangUpOngoingCall() { CallList callList = InCallPresenter.getInstance().getCallList(); if (callList == null) { - StatusBarNotifier.clearAllCallNotifications(context); + StatusBarNotifier.clearAllCallNotifications(); LogUtil.e("NotificationBroadcastReceiver.hangUpOngoingCall", "call list is empty"); } else { DialerCall call = callList.getOutgoingCall(); @@ -140,10 +140,10 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { } } - private void answerIncomingCall(Context context, int videoState) { + private void answerIncomingCall(int videoState) { CallList callList = InCallPresenter.getInstance().getCallList(); if (callList == null) { - StatusBarNotifier.clearAllCallNotifications(context); + StatusBarNotifier.clearAllCallNotifications(); LogUtil.e("NotificationBroadcastReceiver.answerIncomingCall", "call list is empty"); } else { DialerCall call = callList.getIncomingCall(); @@ -155,10 +155,10 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver { } } - private void declineIncomingCall(Context context) { + private void declineIncomingCall() { CallList callList = InCallPresenter.getInstance().getCallList(); if (callList == null) { - StatusBarNotifier.clearAllCallNotifications(context); + StatusBarNotifier.clearAllCallNotifications(); LogUtil.e("NotificationBroadcastReceiver.declineIncomingCall", "call list is empty"); } else { DialerCall call = callList.getIncomingCall(); diff --git a/java/com/android/incallui/StatusBarNotifier.java b/java/com/android/incallui/StatusBarNotifier.java index becfad4ab..86ad9ffe5 100644 --- a/java/com/android/incallui/StatusBarNotifier.java +++ b/java/com/android/incallui/StatusBarNotifier.java @@ -28,7 +28,6 @@ import static com.android.incallui.NotificationBroadcastReceiver.ACTION_TURN_OFF import static com.android.incallui.NotificationBroadcastReceiver.ACTION_TURN_ON_SPEAKER; import android.Manifest; -import android.app.ActivityManager; import android.app.Notification; import android.app.PendingIntent; import android.content.Context; @@ -74,7 +73,6 @@ import com.android.dialer.enrichedcall.Session; import com.android.dialer.lettertile.LetterTileDrawable; import com.android.dialer.lettertile.LetterTileDrawable.ContactType; import com.android.dialer.multimedia.MultimediaData; -import com.android.dialer.notification.DialerNotificationManager; import com.android.dialer.notification.NotificationChannelId; import com.android.dialer.oem.MotorolaUtils; import com.android.dialer.util.DrawableConverter; @@ -86,12 +84,12 @@ import com.android.incallui.audiomode.AudioModeProvider; import com.android.incallui.call.CallList; import com.android.incallui.call.DialerCall; import com.android.incallui.call.DialerCallListener; +import com.android.incallui.call.TelecomAdapter; import com.android.incallui.ringtone.DialerRingtoneManager; import com.android.incallui.ringtone.InCallTonePlayer; import com.android.incallui.ringtone.ToneGeneratorFactory; import com.android.incallui.videotech.utils.SessionModificationState; import java.util.List; -import java.util.Locale; import java.util.Objects; /** This class adds Notifications to the status bar for the in-call experience. */ @@ -100,7 +98,6 @@ public class StatusBarNotifier EnrichedCallManager.StateChangedListener, AudioModeProvider.AudioModeListener { - private static final String NOTIFICATION_TAG = "STATUS_BAR_NOTIFIER"; private static final int NOTIFICATION_ID = 1; // Notification types @@ -146,12 +143,12 @@ public class StatusBarNotifier * Should only be called from a irrecoverable state where it is necessary to dismiss all * notifications. */ - static void clearAllCallNotifications(Context context) { + static void clearAllCallNotifications() { LogUtil.e( "StatusBarNotifier.clearAllCallNotifications", "something terrible happened, clear all InCall notifications"); - DialerNotificationManager.cancel(context, NOTIFICATION_TAG, NOTIFICATION_ID); + TelecomAdapter.getInstance().stopForegroundNotification(); } private static int getWorkStringFromPersonalString(int resId) { @@ -219,10 +216,9 @@ public class StatusBarNotifier setStatusBarCallListener(null); } if (mCurrentNotification != NOTIFICATION_NONE) { - LogUtil.i("StatusBarNotifier.cancelNotification", "cancel"); - DialerNotificationManager.cancel(mContext, NOTIFICATION_TAG, NOTIFICATION_ID); + TelecomAdapter.getInstance().stopForegroundNotification(); + mCurrentNotification = NOTIFICATION_NONE; } - mCurrentNotification = NOTIFICATION_NONE; } /** @@ -390,7 +386,7 @@ public class StatusBarNotifier "Canceling old notification so this one can be noisy"); // Moving from a non-interuptive notification (or none) to a noisy one. Cancel the old // notification (if there is one) so the fullScreenIntent or HUN will show - DialerNotificationManager.cancel(mContext, NOTIFICATION_TAG, NOTIFICATION_ID); + TelecomAdapter.getInstance().stopForegroundNotification(); } break; case NOTIFICATION_INCOMING_CALL_QUIET: @@ -404,6 +400,8 @@ public class StatusBarNotifier builder.setColorized(true); builder.setChannelId(NotificationChannelId.ONGOING_CALL); } + // This will be ignored on O+ and handled by the channel + builder.setPriority(Notification.PRIORITY_MAX); break; default: break; @@ -414,8 +412,7 @@ public class StatusBarNotifier builder.setSmallIcon(iconResId); builder.setContentTitle(contentTitle); builder.setLargeIcon(largeIcon); - builder.setColor( - mContext.getResources().getColor(R.color.dialer_theme_color, mContext.getTheme())); + builder.setColor(InCallPresenter.getInstance().getThemeColorManager().getPrimaryColor()); if (isVideoUpgradeRequest) { builder.setUsesChronometer(false); @@ -451,22 +448,9 @@ public class StatusBarNotifier "StatusBarNotifier.buildAndSendNotification", "displaying notification for " + notificationType); - try { - DialerNotificationManager.notify(mContext, NOTIFICATION_TAG, NOTIFICATION_ID, notification); - } catch (RuntimeException e) { - // TODO(b/34744003): Move the memory stats into silent feedback PSD. - ActivityManager activityManager = mContext.getSystemService(ActivityManager.class); - ActivityManager.MemoryInfo memoryInfo = new ActivityManager.MemoryInfo(); - activityManager.getMemoryInfo(memoryInfo); - throw new RuntimeException( - String.format( - Locale.US, - "Error displaying notification with photo type: %d (low memory? %b, availMem: %d)", - contactInfo.photoType, - memoryInfo.lowMemory, - memoryInfo.availMem), - e); - } + // If a notification exists, this will only update it. + TelecomAdapter.getInstance().startForegroundNotification(NOTIFICATION_ID, notification); + Trace.endSection(); call.getLatencyReport().onNotificationShown(); mCurrentNotification = notificationType; diff --git a/java/com/android/incallui/call/TelecomAdapter.java b/java/com/android/incallui/call/TelecomAdapter.java index 005278bff..0c0bbd473 100644 --- a/java/com/android/incallui/call/TelecomAdapter.java +++ b/java/com/android/incallui/call/TelecomAdapter.java @@ -16,12 +16,14 @@ package com.android.incallui.call; +import android.app.Notification; import android.content.ActivityNotFoundException; import android.content.Intent; import android.os.Looper; import android.support.annotation.MainThread; import android.support.annotation.VisibleForTesting; import android.telecom.InCallService; +import com.android.dialer.common.Assert; import com.android.dialer.common.LogUtil; import java.util.List; @@ -167,4 +169,24 @@ public class TelecomAdapter implements InCallServiceListener { } return false; } + + /** + * Start a foreground notification. Calling it multiple times with the same id only updates the + * existing notification. Whoever called this function are responsible for calling {@link + * #stopForegroundNotification()} to remove the notification. + */ + public void startForegroundNotification(int id, Notification notification) { + Assert.isNotNull( + mInCallService, "No inCallService available for starting foreground notification"); + mInCallService.startForeground(id, notification); + } + + /** + * Stop a started foreground notification. This does not stop {@code mInCallService} from running. + */ + public void stopForegroundNotification() { + Assert.isNotNull( + mInCallService, "No inCallService available for stopping foreground notification"); + mInCallService.stopForeground(true /*removeNotification*/); + } } -- cgit v1.2.3 From 5ee0b1e574ed93c7000e355e4a6b03fb9ed8aaba Mon Sep 17 00:00:00 2001 From: zachh Date: Tue, 3 Oct 2017 17:27:01 -0700 Subject: Only show the most recent call type icon in the new call log, instead of the last 3. This is according to the latest PRD: https://docs.google.com/document/d/1FLoQ6kNYL-QKplbniJAIUCHku87S9eYuYPs6IXe-U78 Also cleaned up warnings in CallLogQueryHandler. Screenshot: https://screenshot.googleplex.com/Z7p4BRVpLpE Bug: 34672501 Test: unit PiperOrigin-RevId: 170941445 Change-Id: Ibf79b70eda3837ea46d365729aaed0a87961e42b --- .../database/AnnotatedCallLogDatabaseHelper.java | 2 +- .../calllog/database/annotated_call_log.proto | 15 ------ .../contract/AnnotatedCallLogContract.java | 27 ++++------ .../systemcalllog/SystemCallLogDataSource.java | 42 ++++++--------- .../ui/CoalescedAnnotatedCallLogCursorLoader.java | 17 ++---- .../dialer/calllog/ui/NewCallLogViewHolder.java | 16 +++--- .../dialer/database/CallLogQueryHandler.java | 61 +++++----------------- 7 files changed, 54 insertions(+), 126 deletions(-) delete mode 100644 java/com/android/dialer/calllog/database/annotated_call_log.proto (limited to 'java') diff --git a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java index e1ec0f6b1..40d922f41 100644 --- a/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java +++ b/java/com/android/dialer/calllog/database/AnnotatedCallLogDatabaseHelper.java @@ -54,7 +54,7 @@ class AnnotatedCallLogDatabaseHelper extends SQLiteOpenHelper { .append(AnnotatedCallLog.IS_VOICEMAIL + " integer, ") // Columns only in AnnotatedCallLog .append(AnnotatedCallLog.NUMBER + " blob, ") - .append(AnnotatedCallLog.TYPE + " integer") + .append(AnnotatedCallLog.CALL_TYPE + " integer") .append(");") .toString(); diff --git a/java/com/android/dialer/calllog/database/annotated_call_log.proto b/java/com/android/dialer/calllog/database/annotated_call_log.proto deleted file mode 100644 index de2bc5f14..000000000 --- a/java/com/android/dialer/calllog/database/annotated_call_log.proto +++ /dev/null @@ -1,15 +0,0 @@ -syntax = "proto2"; - -option java_package = "com.android.dialer"; -option java_multiple_files = true; -option optimize_for = LITE_RUNTIME; - -// DIALER_SCRUB.UNCOMMENT_IN_OPEN_SOURCE option optimize_for = LITE_RUNTIME; - -package com.android.dialer; - -// A list of android.provider.CallLog.Calls.TYPE values ordered from newest to -// oldest. -message CallTypes { - repeated int32 type = 1; -} diff --git a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java index 25950f6b9..d466da9ae 100644 --- a/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java +++ b/java/com/android/dialer/calllog/database/contract/AnnotatedCallLogContract.java @@ -148,6 +148,13 @@ public class AnnotatedCallLogContract { */ String IS_VOICEMAIL = "is_voicemail"; + /** + * Copied from {@link android.provider.CallLog.Calls#TYPE}. + * + *

Type: INTEGER (int) + */ + String CALL_TYPE = "call_type"; + String[] ALL_COMMON_COLUMNS = new String[] { _ID, @@ -165,7 +172,8 @@ public class AnnotatedCallLogContract { PHONE_ACCOUNT_COLOR, FEATURES, IS_BUSINESS, - IS_VOICEMAIL + IS_VOICEMAIL, + CALL_TYPE }; } @@ -196,13 +204,6 @@ public class AnnotatedCallLogContract { *

Type: BLOB */ public static final String NUMBER = "number"; - - /** - * Copied from {@link android.provider.CallLog.Calls#TYPE}. - * - *

Type: INTEGER (int) - */ - public static final String TYPE = "type"; } /** @@ -232,19 +233,11 @@ public class AnnotatedCallLogContract { */ public static final String NUMBER_CALLS = "number_calls"; - /** - * The call types of the most recent 3 calls, encoded as a CallTypes proto. - * - *

TYPE: BLOB - */ - public static final String CALL_TYPES = "call_types"; - /** * Columns that are only in the {@link CoalescedAnnotatedCallLog} but not the {@link * AnnotatedCallLog}. */ - private static final String[] COLUMNS_ONLY_IN_COALESCED_CALL_LOG = - new String[] {NUMBER_CALLS, CALL_TYPES}; + private static final String[] COLUMNS_ONLY_IN_COALESCED_CALL_LOG = new String[] {NUMBER_CALLS}; /** All columns in the {@link CoalescedAnnotatedCallLog}. */ public static final String[] ALL_COLUMNS = diff --git a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java index 1bdbb8a1b..d6ad618b3 100644 --- a/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java +++ b/java/com/android/dialer/calllog/datasources/systemcalllog/SystemCallLogDataSource.java @@ -38,9 +38,7 @@ import android.telecom.PhoneAccount; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.ArraySet; -import com.android.dialer.CallTypes; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.AnnotatedCallLog; -import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; import com.android.dialer.calllog.datasources.CallLogDataSource; import com.android.dialer.calllog.datasources.CallLogMutations; import com.android.dialer.calllog.datasources.util.RowCombiner; @@ -153,30 +151,20 @@ public class SystemCallLogDataSource implements CallLogDataSource { @Override public ContentValues coalesce(List individualRowsSortedByTimestampDesc) { // TODO(zachh): Complete implementation. - ContentValues coalescedValues = - new RowCombiner(individualRowsSortedByTimestampDesc) - .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) - .useMostRecentLong(AnnotatedCallLog.NEW) - .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL) - .useMostRecentString(AnnotatedCallLog.NAME) - .useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER) - .useMostRecentString(AnnotatedCallLog.PHOTO_URI) - .useMostRecentLong(AnnotatedCallLog.PHOTO_ID) - .useMostRecentString(AnnotatedCallLog.LOOKUP_URI) - .useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION) - .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL) - .useSingleValueLong(AnnotatedCallLog.PHONE_ACCOUNT_COLOR) - .combine(); - - CallTypes.Builder callTypes = CallTypes.newBuilder(); - // Store a maximum of 3 call types since that's all we show to users via icons. - for (int i = 0; i < 3 && i < individualRowsSortedByTimestampDesc.size(); i++) { - callTypes.addType( - individualRowsSortedByTimestampDesc.get(i).getAsInteger(AnnotatedCallLog.TYPE)); - } - coalescedValues.put(CoalescedAnnotatedCallLog.CALL_TYPES, callTypes.build().toByteArray()); - - return coalescedValues; + return new RowCombiner(individualRowsSortedByTimestampDesc) + .useMostRecentLong(AnnotatedCallLog.TIMESTAMP) + .useMostRecentLong(AnnotatedCallLog.NEW) + .useMostRecentString(AnnotatedCallLog.NUMBER_TYPE_LABEL) + .useMostRecentString(AnnotatedCallLog.NAME) + .useMostRecentString(AnnotatedCallLog.FORMATTED_NUMBER) + .useMostRecentString(AnnotatedCallLog.PHOTO_URI) + .useMostRecentLong(AnnotatedCallLog.PHOTO_ID) + .useMostRecentString(AnnotatedCallLog.LOOKUP_URI) + .useMostRecentString(AnnotatedCallLog.GEOCODED_LOCATION) + .useSingleValueString(AnnotatedCallLog.PHONE_ACCOUNT_LABEL) + .useSingleValueLong(AnnotatedCallLog.PHONE_ACCOUNT_COLOR) + .useMostRecentLong(AnnotatedCallLog.CALL_TYPE) + .combine(); } @TargetApi(Build.VERSION_CODES.M) // Uses try-with-resources @@ -286,7 +274,7 @@ public class SystemCallLogDataSource implements CallLogDataSource { contentValues.put(AnnotatedCallLog.NUMBER, numberAsProtoBytes); } - contentValues.put(AnnotatedCallLog.TYPE, type); + contentValues.put(AnnotatedCallLog.CALL_TYPE, type); contentValues.put(AnnotatedCallLog.NAME, cachedName); contentValues.put(AnnotatedCallLog.FORMATTED_NUMBER, formattedNumber); contentValues.put(AnnotatedCallLog.PHOTO_URI, cachedPhotoUri); diff --git a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java index d89338350..13a801ac8 100644 --- a/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java +++ b/java/com/android/dialer/calllog/ui/CoalescedAnnotatedCallLogCursorLoader.java @@ -19,12 +19,8 @@ package com.android.dialer.calllog.ui; import android.content.Context; import android.database.Cursor; import android.support.annotation.ColorInt; -import android.support.annotation.NonNull; import android.support.v4.content.CursorLoader; -import com.android.dialer.CallTypes; import com.android.dialer.calllog.database.contract.AnnotatedCallLogContract.CoalescedAnnotatedCallLog; -import com.android.dialer.common.Assert; -import com.google.protobuf.InvalidProtocolBufferException; /** CursorLoader for the coalesced annotated call log. */ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader { @@ -47,8 +43,8 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader { private static final int FEATURES = 13; private static final int IS_BUSINESS = 14; private static final int IS_VOICEMAIL = 15; - private static final int NUMBER_CALLS = 16; - private static final int CALL_TYPES = 17; + private static final int TYPE = 16; + private static final int NUMBER_CALLS = 17; /** Convenience class for accessing values using an abbreviated syntax. */ static final class Row { @@ -127,13 +123,8 @@ final class CoalescedAnnotatedCallLogCursorLoader extends CursorLoader { return cursor.getInt(NUMBER_CALLS); } - @NonNull - CallTypes callTypes() { - try { - return CallTypes.parseFrom(cursor.getBlob(CALL_TYPES)); - } catch (InvalidProtocolBufferException e) { - throw Assert.createAssertionFailException("Couldn't parse call types", e); - } + int callType() { + return cursor.getInt(TYPE); } } diff --git a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java index e198a38e8..8ac419e56 100644 --- a/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java +++ b/java/com/android/dialer/calllog/ui/NewCallLogViewHolder.java @@ -66,8 +66,7 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder { primaryTextView.setText(buildPrimaryText(row)); secondaryTextView.setText(buildSecondaryText(row)); - if (row.isNew()) { - // TODO(zachh): Figure out correct styling for new/missed/unread calls. + if (isNewMissedCall(row)) { primaryTextView.setTextAppearance(R.style.primary_textview_new_call); // TODO(zachh): Styling for call type icons when the call is new. secondaryTextView.setTextAppearance(R.style.secondary_textview_new_call); @@ -95,6 +94,12 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder { return primaryText.toString(); } + private boolean isNewMissedCall(CoalescedAnnotatedCallLogCursorLoader.Row row) { + // Show missed call styling if the most recent call in the group was missed and it is still + // marked as NEW. It is not clear what IS_READ should be used for and it is currently not used. + return row.callType() == Calls.MISSED_TYPE && row.isNew(); + } + private String buildSecondaryText(CoalescedAnnotatedCallLogCursorLoader.Row row) { /* * Rules: (Duo video, )?$Label|$Location • Date @@ -158,10 +163,9 @@ final class NewCallLogViewHolder extends RecyclerView.ViewHolder { } private void setSecondaryCallTypes(Row row) { - // Only call type icons are shown before the secondary text. - for (int callType : row.callTypes().getTypeList()) { - secondaryCallTypeIconsView.add(callType); - } + // Only call type icon is shown before the secondary text. + secondaryCallTypeIconsView.add(row.callType()); + // TODO(zachh): Per new mocks, may need to add method to CallTypeIconsView to disable coloring. } diff --git a/java/com/android/dialer/database/CallLogQueryHandler.java b/java/com/android/dialer/database/CallLogQueryHandler.java index 4867d9dce..35250d668 100644 --- a/java/com/android/dialer/database/CallLogQueryHandler.java +++ b/java/com/android/dialer/database/CallLogQueryHandler.java @@ -54,12 +54,9 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { */ public static final int CALL_TYPE_ALL = -1; - private static final String TAG = "CallLogQueryHandler"; private static final int NUM_LOGS_TO_DISPLAY = 1000; /** The token for the query to fetch the old entries from the call log. */ private static final int QUERY_CALLLOG_TOKEN = 54; - /** The token for the query to mark all missed calls as old after seeing the call log. */ - private static final int UPDATE_MARK_AS_OLD_TOKEN = 55; /** The token for the query to mark all missed calls as read after seeing the call log. */ private static final int UPDATE_MARK_MISSED_CALL_AS_READ_TOKEN = 56; /** The token for the query to fetch voicemail status messages. */ @@ -82,7 +79,7 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { Context context, ContentResolver contentResolver, Listener listener, int limit) { super(contentResolver); mContext = context.getApplicationContext(); - mListener = new WeakReference(listener); + mListener = new WeakReference<>(listener); mLogLimit = limit; } @@ -107,10 +104,6 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { } } - public void fetchCalls(int callType) { - fetchCalls(callType, 0); - } - public void fetchVoicemailStatus() { StringBuilder where = new StringBuilder(); List selectionArgs = new ArrayList<>(); @@ -226,28 +219,6 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { cancelOperation(QUERY_CALLLOG_TOKEN); } - /** Updates all new calls to mark them as old. */ - public void markNewCallsAsOld() { - if (!PermissionsUtil.hasPhonePermissions(mContext)) { - return; - } - // Mark all "new" calls as not new anymore. - StringBuilder where = new StringBuilder(); - where.append(Calls.NEW); - where.append(" = 1"); - - ContentValues values = new ContentValues(1); - values.put(Calls.NEW, "0"); - - startUpdate( - UPDATE_MARK_AS_OLD_TOKEN, - null, - TelecomUtil.getCallLogUri(mContext), - values, - where.toString(), - null); - } - /** Updates all missed calls to mark them as read. */ public void markMissedCallsAsRead() { if (!PermissionsUtil.hasPhonePermissions(mContext)) { @@ -316,19 +287,19 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { */ private boolean updateAdapterData(Cursor cursor) { final Listener listener = mListener.get(); - if (listener != null) { - return listener.onCallsFetched(cursor); - } - return false; + return listener != null && listener.onCallsFetched(cursor); } /** @return Query string to get all unread missed calls. */ private String getUnreadMissedCallsQuery() { - StringBuilder where = new StringBuilder(); - where.append(Calls.IS_READ).append(" = 0 OR ").append(Calls.IS_READ).append(" IS NULL"); - where.append(" AND "); - where.append(Calls.TYPE).append(" = ").append(Calls.MISSED_TYPE); - return where.toString(); + return Calls.IS_READ + + " = 0 OR " + + Calls.IS_READ + + " IS NULL" + + " AND " + + Calls.TYPE + + " = " + + Calls.MISSED_TYPE; } private void updateVoicemailStatus(Cursor statusCursor) { @@ -365,7 +336,7 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { void onMissedCallsUnreadCountFetched(Cursor cursor); /** - * Called when {@link CallLogQueryHandler#fetchCalls(int)} complete. Returns true if takes + * Called when {@link CallLogQueryHandler#fetchCalls(int, long)} complete. Returns true if takes * ownership of cursor. */ boolean onCallsFetched(Cursor combinedCursor); @@ -375,9 +346,9 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { * Simple handler that wraps background calls to catch {@link SQLiteException}, such as when the * disk is full. */ - protected class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler { + private class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler { - public CatchingWorkerHandler(Looper looper) { + CatchingWorkerHandler(Looper looper) { super(looper); } @@ -386,11 +357,7 @@ public class CallLogQueryHandler extends NoNullCursorAsyncQueryHandler { try { // Perform same query while catching any exceptions super.handleMessage(msg); - } catch (SQLiteDiskIOException e) { - LogUtil.e("CallLogQueryHandler.handleMessage", "exception on background worker thread", e); - } catch (SQLiteFullException e) { - LogUtil.e("CallLogQueryHandler.handleMessage", "exception on background worker thread", e); - } catch (SQLiteDatabaseCorruptException e) { + } catch (SQLiteDiskIOException | SQLiteFullException | SQLiteDatabaseCorruptException e) { LogUtil.e("CallLogQueryHandler.handleMessage", "exception on background worker thread", e); } catch (IllegalArgumentException e) { LogUtil.e("CallLogQueryHandler.handleMessage", "contactsProvider not present on device", e); -- cgit v1.2.3